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
5267213e9075e0c51ed39142553facae586295dcaaJean-Michel Triviinline void audioManagerPlayerEvent(CAudioPlayer* ap, android::player_state_t 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 Trivi//-----------------------------------------------------------------------------
59143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// get an audio attributes usage for a stream type, but only consider stream types
60143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// that can successfully be set through SLAndroidConfigurationItf. It is invalid to call
61143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// this function with other stream types.
62143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Triviaudio_usage_t usageForStreamType(audio_stream_type_t streamType) {
63143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    switch (streamType) {
64143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_MUSIC:
65143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_MEDIA;
66143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_VOICE_CALL:
67143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_VOICE_COMMUNICATION;
68143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_SYSTEM:
69143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_ASSISTANCE_SONIFICATION;
70143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_RING:
71143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
72143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_ALARM:
73143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_ALARM;
74143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_NOTIFICATION:
75143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_NOTIFICATION;
76143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    default:
77143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        // shouldn't happen, stream types on AudioPlayer have been sanitized by now.
78143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        SL_LOGE("invalid stream type %d when converting to usage", streamType);
79143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return usageForStreamType(ANDROID_DEFAULT_OUTPUT_STREAM_TYPE);
80143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    }
81143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi}
8267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi
83143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi//-----------------------------------------------------------------------------
8413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// FIXME this method will be absorbed into android_audioPlayer_setPlayState() once
8513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//       bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object
8613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel TriviSLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState,
87b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi        AndroidObjectState* pObjState) {
8813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
89b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi    AndroidObjectState objState = *pObjState;
9013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
9113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (playState) {
9213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_STOPPED:
9313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
9413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         ap->stop();
9513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
9613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_PAUSED:
9713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
98ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten         switch (objState) {
9913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_UNINITIALIZED:
10013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             *pObjState = ANDROID_PREPARING;
10113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->prepare();
10213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
10313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_PREPARING:
10413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
10513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_READY:
10613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->pause();
10713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
10813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         default:
10913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
11013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             result = SL_RESULT_INTERNAL_ERROR;
11113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
11213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
11313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
11413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_PLAYING: {
11513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
116ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten         switch (objState) {
11713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_UNINITIALIZED:
11813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             *pObjState = ANDROID_PREPARING;
11913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->prepare();
12013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             // intended fall through
12113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_PREPARING:
12213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             // intended fall through
12313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_READY:
12413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->play();
12513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
12613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         default:
12713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
12813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             result = SL_RESULT_INTERNAL_ERROR;
12913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
13013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
13113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
13213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
13313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     default:
13413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         // checked by caller, should not happen
13513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
13613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         result = SL_RESULT_INTERNAL_ERROR;
13713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
13813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     }
13913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return result;
14113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
14213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
14513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data
14613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// from a URI or FD, to write the decoded audio data to a buffer queue
147f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kastenstatic size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, CAudioPlayer* ap) {
148f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
149f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        // it is not safe to enter the callback (the player is about to go away)
150f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        return 0;
15113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
152f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    size_t sizeConsumed = 0;
1534e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    SL_LOGD("received %zu bytes from decoder", size);
15413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    slBufferQueueCallback callback = NULL;
15513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    void * callbackPContext = NULL;
15613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
15713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // push decoded data to the buffer queue
15813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    object_lock_exclusive(&ap->mObject);
15913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (ap->mBufferQueue.mState.count != 0) {
16113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
16213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        BufferHeader *oldFront = ap->mBufferQueue.mFront;
16413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        BufferHeader *newFront = &oldFront[1];
16513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
16713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) {
16813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // room to consume the whole or rest of the decoded data in one shot
16913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mSizeConsumed += size;
17013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // consume data but no callback to the BufferQueue interface here
17164c3fe7bd86951eeac27adca2219ce16eabff58cGlenn Kasten            memcpy(pDest, data, size);
17213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            sizeConsumed = size;
17313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else {
17413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // push as much as possible of the decoded data into the buffer queue
17513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
17613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
17713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // the buffer at the head of the buffer queue is full, update the state
17813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mSizeConsumed = 0;
17922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten            if (newFront == &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) {
18013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                newFront = ap->mBufferQueue.mArray;
18113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
18213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mFront = newFront;
18313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
18413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mState.count--;
18513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mState.playIndex++;
18613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // consume data
18764c3fe7bd86951eeac27adca2219ce16eabff58cGlenn Kasten            memcpy(pDest, data, sizeConsumed);
18813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // data has been copied to the buffer, and the buffer queue state has been updated
18913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // we will notify the client if applicable
19013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            callback = ap->mBufferQueue.mCallback;
19113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // save callback data
19213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            callbackPContext = ap->mBufferQueue.mContext;
19313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
19413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
19513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    } else {
19613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // no available buffers in the queue to write the decoded data
19713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        sizeConsumed = 0;
19813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
19913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
20013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    object_unlock_exclusive(&ap->mObject);
20113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // notify client
20213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (NULL != callback) {
20313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
20413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
20513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
206f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    ap->mCallbackProtector->exitCb();
20713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return sizeConsumed;
20813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
20913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
210712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi
211712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi//-----------------------------------------------------------------------------
212ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#define LEFT_CHANNEL_MASK  AUDIO_CHANNEL_OUT_FRONT_LEFT
213ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#define RIGHT_CHANNEL_MASK AUDIO_CHANNEL_OUT_FRONT_RIGHT
2146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
215fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kastenvoid android_audioPlayer_volumeUpdate(CAudioPlayer* ap)
216fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten{
217fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(ap != NULL);
2184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
219fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // the source's channel count, where zero means unknown
22099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    SLuint8 channelCount = ap->mNumChannels;
2211fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
222fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // whether each channel is audible
223fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    bool leftAudibilityFactor, rightAudibilityFactor;
2241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
225fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // mute has priority over solo
226e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (channelCount >= STEREO_CHANNELS) {
227b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
2281fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left muted
229fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            leftAudibilityFactor = false;
2301fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
2311fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left not muted
232b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
2331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left soloed
234fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                leftAudibilityFactor = true;
2351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
2361fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left not soloed
237b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
2381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // right solo silences left
239fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    leftAudibilityFactor = false;
2401fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
2411fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and left is not muted
242fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    leftAudibilityFactor = true;
2431fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
2441fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
2451fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
2461fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
247b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
2481fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right muted
249fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            rightAudibilityFactor = false;
2501fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
2511fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right not muted
252b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
2531fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right soloed
254fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                rightAudibilityFactor = true;
2551fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
2561fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right not soloed
257b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
2581fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left solo silences right
259fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    rightAudibilityFactor = false;
2601fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
2611fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and right is not muted
262fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    rightAudibilityFactor = true;
2631fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
2641fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
2651fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
266fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
267fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // channel mute and solo are ignored for mono and unknown channel count sources
268fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    } else {
269fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftAudibilityFactor = true;
270fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightAudibilityFactor = true;
271fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
272fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
27399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // compute volumes without setting
27499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    const bool audibilityFactors[2] = {leftAudibilityFactor, rightAudibilityFactor};
27599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float volumes[2];
27699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    android_player_volumeUpdate(volumes, &ap->mVolume, channelCount, ap->mAmplFromDirectLevel,
27799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            audibilityFactors);
27899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float leftVol = volumes[0], rightVol = volumes[1];
27999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
28099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // set volume on the underlying media player or audio track
28199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (ap->mAPlayer != 0) {
28299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        ap->mAPlayer->setVolume(leftVol, rightVol);
283d2195fb3559e334f543ded7da2f9a87e10e89c40Jean-Michel Trivi    } else if (ap->mTrackPlayer != 0) {
284d73b1134e795fa521e71dc567b6b3bde9cdd498dEric Laurent        ap->mTrackPlayer->setPlayerVolume(leftVol, rightVol);
28599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
28699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
28799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // changes in the AudioPlayer volume must be reflected in the send level:
28899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    //  in SLEffectSendItf or in SLAndroidEffectSendItf?
28999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // FIXME replace interface test by an internal API once we have one.
29099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (NULL != ap->mEffectSend.mItf) {
29199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        for (unsigned int i=0 ; i<AUX_MAX ; i++) {
29299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            if (ap->mEffectSend.mEnableLevels[i].mEnable) {
29399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                android_fxSend_setSendLevel(ap,
29499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                        ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
29599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                // there's a single aux bus on Android, so we can stop looking once the first
29699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                // aux effect is found.
29799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                break;
29899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            }
29999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        }
30099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else if (NULL != ap->mAndroidEffectSend.mItf) {
30199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
30299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
30399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten}
30499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
30599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten// Called by android_audioPlayer_volumeUpdate and android_mediaPlayer_volumeUpdate to compute
30699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten// volumes, but setting volumes is handled by the caller.
30799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
30899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kastenvoid android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf, unsigned
30999b927751677abfb60a388d65dfeed1fed1db12cGlenn KastenchannelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/)
31099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten{
31199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    assert(pVolumes != NULL);
31299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    assert(volumeItf != NULL);
31399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // OK for audibilityFactors to be NULL
31499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
31599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    bool leftAudibilityFactor, rightAudibilityFactor;
31699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
317fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // apply player mute factor
318fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // note that AudioTrack has mute() but not MediaPlayer, so it's easier to use volume
31999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // to mute for both rather than calling mute() for AudioTrack
32099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
32199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player is muted
32299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (volumeItf->mMute) {
323fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftAudibilityFactor = false;
324fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightAudibilityFactor = false;
32599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player isn't muted, and channel mute/solo audibility factors are available (AudioPlayer)
32699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else if (audibilityFactors != NULL) {
32799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftAudibilityFactor = audibilityFactors[0];
32899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightAudibilityFactor = audibilityFactors[1];
32999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player isn't muted, and channel mute/solo audibility factors aren't available (MediaPlayer)
33099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
33199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftAudibilityFactor = true;
33299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightAudibilityFactor = true;
3331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
3346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
3356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
33699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    //   amplification (or attenuation) from volume level
33799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float amplFromVolLevel = sles_to_android_amplification(volumeItf->mLevel);
338ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi    //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
33999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float leftVol  = amplFromVolLevel * amplFromDirectLevel;
34099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float rightVol = leftVol;
341a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
342f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    // amplification from stereo position
34399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (volumeItf->mEnableStereoPosition) {
34499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // Left/right amplification (can be attenuations) factors derived for the StereoPosition
34599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        float amplFromStereoPos[STEREO_CHANNELS];
34699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // panning law depends on content channel count: mono to stereo panning vs stereo balance
34799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        if (1 == channelCount) {
34899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            // mono to stereo panning
34999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            double theta = (1000+volumeItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
35099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            amplFromStereoPos[0] = cos(theta);
35199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            amplFromStereoPos[1] = sin(theta);
352fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        // channel count is 0 (unknown), 2 (stereo), or > 2 (multi-channel)
353f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
354f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo balance
35599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            if (volumeItf->mStereoPosition > 0) {
35699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[0] = (1000-volumeItf->mStereoPosition)/1000.0f;
35799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[1] = 1.0f;
3586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
35999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[0] = 1.0f;
36099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[1] = (1000+volumeItf->mStereoPosition)/1000.0f;
3616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
3626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
36399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftVol  *= amplFromStereoPos[0];
36499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightVol *= amplFromStereoPos[1];
365f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
366f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
367fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // apply audibility factors
368fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (!leftAudibilityFactor) {
369fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftVol = 0.0;
370fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
371fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (!rightAudibilityFactor) {
372fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightVol = 0.0;
373fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
374fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
37599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // return the computed volumes
37699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    pVolumes[0] = leftVol;
37799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    pVolumes[1] = rightVol;
3784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
3794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
381e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
38249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
3834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
3844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
3854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3864614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
3874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
3884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
3894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
3904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
3924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
3934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
3944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
3954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
3964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
398e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
39949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
4004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
4014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
4024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
4044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
4054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
4064614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
4074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
4094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
4104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
4114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
416e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
4174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
4184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
4194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
4214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
4224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
4234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
4244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
4254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if ((NULL != callback) && headStalled) {
4274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
428f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
429f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi}
430f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
43124430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi
432e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi//-----------------------------------------------------------------------------
433e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi/**
434e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
435e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *
436e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
437e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       needs to be changed when the player reaches the end of the content to play. This is
438e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       relative to what the specification describes for buffer queues vs the
439e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
440e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
441e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          buffers in the queue, the playing of audio data stops. The player remains in the
442e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          SL_PLAYSTATE_PLAYING state."
443e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
444e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          of the current content and the player has paused."
445e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi */
446fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kastenvoid audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
447fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        bool needToLock) {
44825d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
44925d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    //        needToLock);
450e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    slPlayCallback playCallback = NULL;
451e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    void * playContext = NULL;
452e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    // SLPlayItf callback or no callback?
453fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    if (needToLock) {
454ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        interface_lock_exclusive(&ap->mPlay);
455fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
456e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
457e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playCallback = ap->mPlay.mCallback;
458e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playContext = ap->mPlay.mContext;
459e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
46025d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    if (setPlayStateToPaused) {
461ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
462ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi    }
463ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi    if (needToLock) {
464ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        interface_unlock_exclusive(&ap->mPlay);
465fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
466377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten    // enqueue callback with no lock held
467e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (NULL != playCallback) {
468dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
469dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten        (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
470dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#else
471377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
472377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten                SL_PLAYEVENT_HEADATEND);
473377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        if (SL_RESULT_SUCCESS != result) {
474a6c69c7e1665b38da8d6784e65210acbe501b92cSteve Block            ALOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback,
475377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten                    &ap->mPlay.mItf, playContext);
476377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        }
477dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#endif
478e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
47925d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi
480e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi}
481e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
482a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
483a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi//-----------------------------------------------------------------------------
48475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
48575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
486a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten    SL_LOGV("type %d", type);
48775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
4880bfed90f3b312f7c8f2b744efcf62f1992661d6cGlenn Kasten    audio_stream_type_t newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
489ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (type) {
49075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_VOICE:
491ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_VOICE_CALL;
49275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
49375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_SYSTEM:
494ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_SYSTEM;
49575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
49675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_RING:
497ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_RING;
49875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
49975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_MEDIA:
500ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_MUSIC;
50175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_ALARM:
503ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_ALARM;
50475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_NOTIFICATION:
506ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_NOTIFICATION;
50775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    default:
50975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
51075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
51175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
51275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
51375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
51475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    // stream type needs to be set before the object is realized
51567213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    // (ap->mTrackPlayer->mAudioTrack is supposed to be NULL until then)
5165f71e35da153d194d805e030ab38935599e065d2Jean-Michel Trivi    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
51775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
51875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PRECONDITIONS_VIOLATED;
51975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
52075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        ap->mStreamType = newStreamType;
52175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
52275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
52375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
52475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
52575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
5268c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//-----------------------------------------------------------------------------
5278c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioPlayer_setPerformanceMode(CAudioPlayer* ap, SLuint32 mode) {
5288c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLresult result = SL_RESULT_SUCCESS;
5298c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SL_LOGV("performance mode set to %d", mode);
5308c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5318c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
5328c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (mode) {
5338c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_LATENCY:
5348c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_LATENCY;
5358c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5368c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS:
5378c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
5388c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5398c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_NONE:
5408c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_NONE;
5418c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5428c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_POWER_SAVING:
5438c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING;
5448c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5458c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
5468c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN);
5478c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_PARAMETER_INVALID;
5488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
5508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    // performance mode needs to be set before the object is realized
55267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    // (ap->mTrackPlayer->mAudioTrack is supposed to be NULL until then)
5538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
5548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED);
5558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_PRECONDITIONS_VIOLATED;
5568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else {
5578c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        ap->mPerformanceMode = perfMode;
5588c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
5598c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5608c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    return result;
5618c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
56275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
56375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
56475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
56575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
56675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
567ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mStreamType) {
568ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_VOICE_CALL:
56975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_VOICE;
57075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
571ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_SYSTEM:
57275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_SYSTEM;
57375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
574ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_RING:
57575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_RING;
57675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
577ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_DEFAULT:
578ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_MUSIC:
57975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_MEDIA;
58075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
581ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_ALARM:
58275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_ALARM;
58375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
584ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_NOTIFICATION:
58575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_NOTIFICATION;
58675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
58775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    default:
58875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_INTERNAL_ERROR;
58975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_MEDIA;
59075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
59175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
59275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
59375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
59475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
59575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
5968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//-----------------------------------------------------------------------------
5978c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioPlayer_getPerformanceMode(CAudioPlayer* ap, SLuint32 *pMode) {
5988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLresult result = SL_RESULT_SUCCESS;
5998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
6008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (ap->mPerformanceMode) {
6018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY:
6028c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
6038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
6058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS;
6068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_NONE:
6088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_NONE;
6098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
6118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING;
6128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
6148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_INTERNAL_ERROR;
6158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
6168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6178c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
6188c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
6198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    return result;
6208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
62175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
62275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
623f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivivoid audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
62467213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    if ((ap->mTrackPlayer->mAudioTrack != 0) && (ap->mAuxEffect != 0)) {
625f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi        android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
626f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi    }
627f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi}
628f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi
629f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi
630f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi//-----------------------------------------------------------------------------
63113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/*
6327965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten * returns true if the given data sink is supported by AudioPlayer that doesn't
63313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *   play to an OutputMix object, false otherwise
63413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *
63513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
63613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */
63713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivibool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
63813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    bool result = true;
63913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
64013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
64113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
64213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sinkLocatorType) {
64313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
64413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
64513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
64613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (SL_DATAFORMAT_PCM != sinkFormatType) {
64713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM",
64813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sinkFormatType);
64913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            result = false;
65013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
65113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // it's no use checking the PCM format fields because additional characteristics
65213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // such as the number of channels, or sample size are unknown to the player at this stage
65313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
65413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
65513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    default:
65613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
65713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        result = false;
65813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
65913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
66013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return result;
66213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
66313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
66613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/*
66713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * returns the Android object type if the locator type combinations for the source and sinks
66813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *   are supported by this implementation, INVALID_TYPE otherwise
66913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */
67004e38178473bb0ffdb4759956db60dd86aa7e732Glenn Kastenstatic
671e05f49175a60182d29d0e38ee2a214854c279d95Glenn KastenAndroidObjectType audioPlayer_getAndroidObjectTypeForSourceSink(const CAudioPlayer *ap) {
67213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
67313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource;
67413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink;
67513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
67613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
677b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi    AndroidObjectType type = INVALID_TYPE;
67813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
67913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //--------------------------------------
68013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // Sink / source matching check:
68113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // the following source / sink combinations are supported
68213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_BUFFERQUEUE                / SL_DATALOCATOR_OUTPUTMIX
68313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE   / SL_DATALOCATOR_OUTPUTMIX
68413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_OUTPUTMIX
68513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_OUTPUTMIX
68613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_OUTPUTMIX
687bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_BUFFERQUEUE
68813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_BUFFERQUEUE
68913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_BUFFERQUEUE
69013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
69113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
69213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sinkLocatorType) {
69313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
69413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX: {
69513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceLocatorType) {
69613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
69713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   Buffer Queue to AudioTrack
69813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_BUFFERQUEUE:
69913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
7004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_PCM_BUFFERQUEUE;
70113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
70213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
70313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   URI or FD to MediaPlayer
70413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
70513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD:
7064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_URIFD;
70713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
70813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
70913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   Android BufferQueue to MediaPlayer (shared memory streaming)
71013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
7114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE;
71213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
71313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
71413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
71513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
71613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sourceLocatorType);
71713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
71813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
71913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
72013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
72113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
72213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
72313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
72413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceLocatorType) {
72513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
72613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   URI or FD decoded to PCM in a buffer queue
72713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
72813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD:
7294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE;
73013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
73113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
732bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        //   AAC ADTS Android buffer queue decoded to PCM in a buffer queue
733bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
734bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            type = AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE;
735bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            break;
736bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi
73713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
73813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
73913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sourceLocatorType);
74013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
74113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
74213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
74313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
74413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    default:
74513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
74613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
74713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
74813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
74913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return type;
75013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
75113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
75213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
75313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
7547f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi/*
7557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi * Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
7565933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten * from a URI or FD, for prepare, prefetch, and play events
7577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi */
75837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivistatic void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
759c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten
760c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten    // FIXME see similar code and comment in player_handleMediaPlayerEventNotifications
761c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten
762de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL == user) {
763de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        return;
764de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
765f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
766de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
7676cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
7686cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi        // it is not safe to enter the callback (the track is about to go away)
7696cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi        return;
7706cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    }
771b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    union {
772b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        char c[sizeof(int)];
773b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        int i;
774b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    } u;
775b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    u.i = event;
776b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
777b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten            "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
778ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (event) {
779f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
78068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    case android::GenericPlayer::kEventPrepared: {
781796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        SL_LOGV("Received GenericPlayer::kEventPrepared for CAudioPlayer %p", ap);
7823ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
783796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // assume no callback
784796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        slPrefetchCallback callback = NULL;
785796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        void* callbackPContext;
786796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        SLuint32 events;
787f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
788796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        object_lock_exclusive(&ap->mObject);
7893ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
790796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // mark object as prepared; same state is used for successful or unsuccessful prepare
791796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        assert(ap->mAndroidObjState == ANDROID_PREPARING);
792796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        ap->mAndroidObjState = ANDROID_READY;
793f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
794796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        if (PLAYER_SUCCESS == data1) {
7957f250a17c145382b866d5d4d7ef23d65fada6236Glenn Kasten            // Most of successful prepare completion for ap->mAPlayer
7967f250a17c145382b866d5d4d7ef23d65fada6236Glenn Kasten            // is handled by GenericPlayer and its subclasses.
797796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        } else {
798f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
799796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten            //  indicate a prefetch error, so we signal it by sending simultaneously two events:
800f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
801f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
802f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
803b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten            if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
804796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                ap->mPrefetchStatus.mLevel = 0;
805796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
806796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
807796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                        (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
808796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    callback = ap->mPrefetchStatus.mCallback;
809796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    callbackPContext = ap->mPrefetchStatus.mContext;
810796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    events = SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE;
811796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                }
812f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            }
813796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        }
814f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
815796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        object_unlock_exclusive(&ap->mObject);
816f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
817796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // callback with no lock held
818796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        if (NULL != callback) {
819796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, events);
8203ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        }
8213ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
82213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
82313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    break;
8243ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
8254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
826b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
827a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            break;
828a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
829ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        slPrefetchCallback callback = NULL;
830ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        void* callbackPContext = NULL;
8318a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
832ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
833ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        interface_lock_exclusive(&ap->mPrefetchStatus);
834ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
835ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
836ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
837ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        }
838ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
839ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        interface_unlock_exclusive(&ap->mPrefetchStatus);
8408a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
841ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        // callback with no lock held
842ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (NULL != callback) {
843ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
844ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
845ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        }
84613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
84713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    break;
848de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
8494ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventPrefetchStatusChange: {
850b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
851a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            break;
852a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
85306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        slPrefetchCallback callback = NULL;
854de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void* callbackPContext = NULL;
8558a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
856de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
8578a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        object_lock_exclusive(&ap->mObject);
858de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
859de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
860de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
861de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
8624ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (data1 >= android::kStatusIntermediate) {
863de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
8644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        } else if (data1 < android::kStatusIntermediate) {
865de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
866de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
8678a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        object_unlock_exclusive(&ap->mObject);
8688a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
869de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
87006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (NULL != callback) {
871de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
87206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
87313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
87413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
875de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
8764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventEndOfStream: {
877fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
87867213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        if ((ap->mTrackPlayer->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
87967213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->mAudioTrack->stop();
8803ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        }
88167213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STOPPED);
88213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
88313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
884de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
885fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    case android::GenericPlayer::kEventChannelCount: {
886fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        object_lock_exclusive(&ap->mObject);
887fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
888fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            ap->mNumChannels = data1;
889fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            android_audioPlayer_volumeUpdate(ap);
890fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        }
891fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        object_unlock_exclusive(&ap->mObject);
892fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        }
893fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        break;
894fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
8955933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    case android::GenericPlayer::kEventPlay: {
8965933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        slPlayCallback callback = NULL;
8975933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        void* callbackPContext = NULL;
8985933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
8995933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        interface_lock_shared(&ap->mPlay);
9005933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        callback = ap->mPlay.mCallback;
9015933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        callbackPContext = ap->mPlay.mContext;
9025933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        interface_unlock_shared(&ap->mPlay);
9035933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
9045933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        if (NULL != callback) {
9055933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
9065933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
9075933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            // synchronous callback requires a synchronous GetPosition implementation
9085933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            (*callback)(&ap->mPlay.mItf, callbackPContext, event);
9095933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#else
9105933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            // asynchronous callback works with any GetPosition implementation
9115933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
9125933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                    callbackPContext, event);
9135933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            if (SL_RESULT_SUCCESS != result) {
914a6c69c7e1665b38da8d6784e65210acbe501b92cSteve Block                ALOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
9155933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                        &ap->mPlay.mItf, callbackPContext, event);
9165933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            }
9175933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#endif
9185933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        }
9195933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        }
9205933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        break;
9215933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
9225e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      case android::GenericPlayer::kEventErrorAfterPrepare: {
923513222822545c3e954176476b263df52a47f43a4Glenn Kasten        SL_LOGV("kEventErrorAfterPrepare");
9245e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9255e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // assume no callback
9265e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        slPrefetchCallback callback = NULL;
9275e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        void* callbackPContext = NULL;
9285e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9295e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        object_lock_exclusive(&ap->mObject);
9305e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
9315e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            ap->mPrefetchStatus.mLevel = 0;
9325e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
9335e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
9345e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                    (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
9355e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                callback = ap->mPrefetchStatus.mCallback;
9365e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                callbackPContext = ap->mPrefetchStatus.mContext;
9375e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            }
9385e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        }
9395e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        object_unlock_exclusive(&ap->mObject);
9405e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9415e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // FIXME there's interesting information in data1, but no API to convey it to client
9425e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        SL_LOGE("Error after prepare: %d", data1);
9435e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9445e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // callback with no lock held
9455e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        if (NULL != callback) {
9465e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
9475e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                    SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
9485e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        }
9495e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9505e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      }
9515e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      break;
9525e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
953e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::GenericPlayer::kEventHasVideoSize:
954e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        //SL_LOGW("Unexpected kEventHasVideoSize");
955e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        break;
9565e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9576a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
9586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
9596a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
9606cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi
9616cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    ap->mCallbackProtector->exitCb();
962a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
963a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
964bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean// From EffectDownmix.h
965ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
966bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kSides = AUDIO_CHANNEL_OUT_SIDE_LEFT | AUDIO_CHANNEL_OUT_SIDE_RIGHT;
967ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
968bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kBacks = AUDIO_CHANNEL_OUT_BACK_LEFT | AUDIO_CHANNEL_OUT_BACK_RIGHT;
969ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
970bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kUnsupported =
971bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER | AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
972bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_CENTER |
973bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT |
974bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER |
975bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT |
976bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_LEFT |
977bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_CENTER |
978bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT;
979bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
980ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
981ff25010cb77455a46357d6dd012631a2599d7bf4Glenn KastenSLresult android_audioPlayer_validateChannelMask(uint32_t mask, uint32_t numChans) {
982bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    // Check that the number of channels falls within bounds.
983ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten    if (numChans == 0 || numChans > FCC_8) {
9844e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGE("Number of channels %u must be between one and %u inclusive", numChans, FCC_8);
985bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        return SL_RESULT_CONTENT_UNSUPPORTED;
986bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
987bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    // Are there the right number of channels in the mask?
9884e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (sles_channel_count_from_mask(mask) != numChans) {
9894e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGE("Channel mask %#x does not match channel count %u", mask, numChans);
990bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        return SL_RESULT_CONTENT_UNSUPPORTED;
991bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
9924e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
9934e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    audio_channel_representation_t representation =
9944e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            sles_to_audio_channel_mask_representation(mask);
9954e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
9964e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
9974e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        return SL_RESULT_SUCCESS;
998bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
9994e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
10004e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // If audio is positional we need to run a set of checks to make sure
10014e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // the positions can be handled by our HDMI-compliant downmixer. Compare with
10024e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // android.media.AudioTrack.isMultichannelConfigSupported
10034e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // and Downmix_foldGeneric (in libeffects).
10044e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (representation == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
10054e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // check against unsupported channels
10064e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if (mask & kUnsupported) {
10074e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Unsupported channels (top or front left/right of center)",
10084e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                    mask);
1009bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
1010bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        }
10114e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that mask has FL/FR if more than one channel specified
10124e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if (numChans > 1 && (mask & AUDIO_CHANNEL_OUT_STEREO) != AUDIO_CHANNEL_OUT_STEREO) {
10134e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Front channels must be present", mask);
1014bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
1015bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        }
10164e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that SIDE is used as a pair (ok if not using SIDE at all)
10174e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if ((mask & kSides) != 0 && (mask & kSides) != kSides) {
10184e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                SL_LOGE("Mask %#x is invalid: Side channels must be used as a pair", mask);
10194e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                return SL_RESULT_CONTENT_UNSUPPORTED;
10204e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
10214e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that BACK is used as a pair (ok if not using BACK at all)
10224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if ((mask & kBacks) != 0 && (mask & kBacks) != kBacks) {
10234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Back channels must be used as a pair", mask);
10244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
10254e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
10264e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        return SL_RESULT_SUCCESS;
1027bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
1028bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
10294e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    SL_LOGE("Unrecognized channel mask representation %#x", representation);
10304e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    return SL_RESULT_CONTENT_UNSUPPORTED;
1031bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean}
103275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1033a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
1034d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
1035c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
103613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // verify that the locator types for the source / sink combination is supported
103713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
103813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
1039c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
1040c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
1041c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
104213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
104313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
10444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
104513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // format check:
104613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
104713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
104813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
104913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
1050e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung    const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
1051e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung
105213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sourceLocatorType) {
1053c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
1054c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
105501e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
105601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
105701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        {
1058c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
105913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1060a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
1061e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung        case SL_ANDROID_DATAFORMAT_PCM_EX: {
1062e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten            const SLAndroidDataFormat_PCM_EX *df_pcm =
1063e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten                    (const SLAndroidDataFormat_PCM_EX *) pAudioSrc->pFormat;
1064df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked representation
1065df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            df_representation = &df_pcm->representation;
106603d4a5ae486538839d02ae8a18e2a5c38bf1e2fbGlenn Kasten            } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
1067c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
106871065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            // checkDataFormat() already did generic checks, now do the Android-specific checks
1069e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten            const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSrc->pFormat;
1070bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            SLresult result = android_audioPlayer_validateChannelMask(df_pcm->channelMask,
1071bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                                                                      df_pcm->numChannels);
1072bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            if (result != SL_RESULT_SUCCESS) {
1073bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                SL_LOGE("Cannot create audio player: unsupported PCM data source with %u channels",
1074bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                        (unsigned) df_pcm->numChannels);
1075bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                return result;
1076c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
1077bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
1078df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked sample rate
1079df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten
1080df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked bits per sample, container size, and representation
1081ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten
1082ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten            // FIXME confirm the following
10831452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            // df_pcm->channelMask: the earlier platform-independent check and the
10841452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            //     upcoming check by sles_to_android_channelMaskOut are sufficient
1085a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten
1086a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten            if (df_pcm->endianness != pAudioPlayer->mObject.mEngine->mEngine.mNativeEndianness) {
108771065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported byte order %u",
108871065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        df_pcm->endianness);
1089c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1090c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
109171065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten
109271065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            // we don't support container size != sample depth
109371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            if (df_pcm->containerSize != df_pcm->bitsPerSample) {
109471065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported container size %u bits for "
109571065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        "sample depth %u bits",
109671065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample);
109771065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
109871065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            }
109971065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten
1100c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
1101c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
1102c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
11038b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten        case XA_DATAFORMAT_RAWIMAGE:
110401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten            SL_LOGE("Cannot create audio player with buffer queue data source "
110549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "without SL_DATAFORMAT_PCM format");
1106c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
1107c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
11088b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            // invalid data format is detected earlier
11098b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            assert(false);
11108b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            return SL_RESULT_INTERNAL_ERROR;
111113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
111201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
1113c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
1114c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
11156fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
11166fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
11176fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
111822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
1119989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        if (NULL == dl_uri->URI) {
1120989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
1121989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
1122989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // URI format
112313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1124989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
1125989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
112609aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten        default:
1127337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
112849e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "SL_DATAFORMAT_MIME format");
1129989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
113013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
113113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // decoding format check
113213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
113313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
113413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
113513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
11366fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
11376fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
11386fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
1139989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //   File Descriptor
1140989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    case SL_DATALOCATOR_ANDROIDFD:
1141989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        {
1142989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // fd is already non null
114313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1144989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
1145989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
114609aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten        default:
1147337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
114809aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten                "without SL_DATAFORMAT_MIME format");
1149989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
115013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
115113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
115213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
115313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
115413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
1155989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } // case SL_DATALOCATOR_ANDROIDFD
1156989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        break;
1157989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //------------------
1158fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //   Stream
1159fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
1160d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    {
1161d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        switch (sourceFormatType) {
1162d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
1163fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        {
1164d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
1165bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            if (NULL == df_mime) {
1166bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                SL_LOGE("MIME type null invalid");
1167bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1168bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            }
1169bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
1170ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten            switch (df_mime->containerType) {
1171bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_MPEG_TS:
1172c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                if (strcasecmp((char*)df_mime->mimeType, (const char *)XA_ANDROID_MIME_MP2TS)) {
1173bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
1174c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                            (char*)df_mime->mimeType, XA_ANDROID_MIME_MP2TS);
1175bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    return SL_RESULT_CONTENT_UNSUPPORTED;
1176bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                }
117736c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) {
117836c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_MPEG_TS");
117936c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    return SL_RESULT_PARAMETER_INVALID;
118036c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                }
1181bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                break;
1182bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_RAW:
1183bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_AAC:
1184c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                if (strcasecmp((char*)df_mime->mimeType, (const char *)SL_ANDROID_MIME_AACADTS) &&
1185bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                        strcasecmp((char*)df_mime->mimeType,
1186bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                                ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
1187bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
1188bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                            (char*)df_mime->mimeType, df_mime->containerType,
1189c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                            SL_ANDROID_MIME_AACADTS);
1190bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    return SL_RESULT_CONTENT_UNSUPPORTED;
1191bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                }
119236c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE) {
119336c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_AAC");
119436c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    return SL_RESULT_PARAMETER_INVALID;
119536c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                }
1196bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                break;
1197bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            default:
1198d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1199bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                                        "that is not fed MPEG-2 TS data or AAC ADTS data");
1200d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1201d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            }
1202d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
1203fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        break;
1204d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        default:
1205d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1206d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                    "without SL_DATAFORMAT_MIME format");
1207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
1208d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
1209d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
1210d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
1211fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //------------------
1212c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
1213c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
1214c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
1215c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
12168b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten    case XA_DATALOCATOR_NATIVEDISPLAY:
1217c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
121813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Cannot create audio player with data locator type 0x%x",
121913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                (unsigned) sourceLocatorType);
1220c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
1221c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
1222fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
122313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                (unsigned) sourceLocatorType);
1224c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
1225c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
1226c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
1227c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
1228c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
1229c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
1230773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
1231a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
12321ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
123383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi// from a buffer queue. This will not be called once the AudioTrack has been destroyed.
1234a84c5e20d9884d7ec7e4b1377a328c1d1a552b70Glenn Kastenstatic void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
1235e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
123683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12376cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
123883ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        // it is not safe to enter the callback (the track is about to go away)
123983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        return;
124083ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    }
124183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12428f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi    void * callbackPContext = NULL;
1243ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (event) {
12446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
124513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_MORE_DATA: {
124683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
1247a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        slPrefetchCallback prefetchCallback = NULL;
1248a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        void *prefetchContext = NULL;
1249a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
12501ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
125183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12521ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
1253e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_lock_exclusive(&ap->mBufferQueue);
125483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12550f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien        if (ap->mBufferQueue.mCallbackPending) {
12560f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            // call callback with lock not held
12570f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            slBufferQueueCallback callback = ap->mBufferQueue.mCallback;
12580f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            if (NULL != callback) {
12590f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                callbackPContext = ap->mBufferQueue.mContext;
12600f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                interface_unlock_exclusive(&ap->mBufferQueue);
12610f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
12620f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                interface_lock_exclusive(&ap->mBufferQueue);
12630f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mCallbackPending = false;
12640f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            }
12650f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien        }
12660f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien
1267e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        if (ap->mBufferQueue.mState.count != 0) {
1268a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten            //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
1269e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
12701ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
1271e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            BufferHeader *oldFront = ap->mBufferQueue.mFront;
1272d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *newFront = &oldFront[1];
12731ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
12740f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t availSource = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
12750f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t availSink = pBuff->size;
12760f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t bytesToCopy = availSource < availSink ? availSource : availSink;
12771452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
12780f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            memcpy(pBuff->raw, pSrc, bytesToCopy);
12790f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien
12800f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            if (bytesToCopy < availSource) {
12810f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mSizeConsumed += bytesToCopy;
12820f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                // pBuff->size is already equal to bytesToCopy in this case
12831ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
12840f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                // consumed an entire buffer, dequeue
12850f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                pBuff->size = bytesToCopy;
1286e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mSizeConsumed = 0;
12871ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
1288e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                        &ap->mBufferQueue.mArray
1289e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                            [ap->mBufferQueue.mNumBuffers + 1])
12901ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
1291e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                    newFront = ap->mBufferQueue.mArray;
12921ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
1293e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mFront = newFront;
12941ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
1295e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.count--;
1296e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.playIndex++;
12970f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mCallbackPending = true;
12981ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
1299e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        } else { // empty queue
1300e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal no data available
13011ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
1302e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
1303e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal we're at the end of the content, but don't pause (see note in function)
1304fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1305e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
1306a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            // signal underflow to prefetch status itf
1307b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten            if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
1308a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
1309a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                ap->mPrefetchStatus.mLevel = 0;
1310a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                // callback or no callback?
1311a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
1312a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
1313a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
1314a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                    prefetchCallback = ap->mPrefetchStatus.mCallback;
1315a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                    prefetchContext  = ap->mPrefetchStatus.mContext;
1316a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                }
1317a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            }
1318a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
1319e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // stop the track so it restarts playing faster when new data is enqueued
132067213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->stop();
13211ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
1322e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_unlock_exclusive(&ap->mBufferQueue);
132383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
132406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        // notify client
1325a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        if (NULL != prefetchCallback) {
1326a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
1327a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            // spec requires separate callbacks for each event
1328a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
1329a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1330a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        SL_PREFETCHEVENT_STATUSCHANGE);
1331a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            }
1332a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
1333a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1334a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        SL_PREFETCHEVENT_FILLLEVELCHANGE);
1335a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            }
1336a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        }
13376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
13386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
13391ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
134013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_MARKER:
134183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_MARKER from AudioTrack");
1342e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleMarker_lockPlay(ap);
13434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
134513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_NEW_POS:
134683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
1347e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleNewPos_lockPlay(ap);
13484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
135013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_UNDERRUN:
135183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
1352e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleUnderrun_lockPlay(ap);
13534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
13559f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten    case android::AudioTrack::EVENT_NEW_IAUDIOTRACK:
13569f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten        // ignore for now
13579f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten        break;
13589f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten
1359e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::AudioTrack::EVENT_BUFFER_END:
1360e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::AudioTrack::EVENT_LOOP_END:
13619f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten    case android::AudioTrack::EVENT_STREAM_END:
1362e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        // These are unexpected so fall through
13636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
1364e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
1365b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1366b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi                (CAudioPlayer *)user);
13676a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
13681ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
136983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
13706cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    ap->mCallbackProtector->exitCb();
13711ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
13721ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
13731ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
13741ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
137572042d4448cee63528c619537321ba73944c6382Glenn Kastenvoid android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1376773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
137772042d4448cee63528c619537321ba73944c6382Glenn Kasten    // pAudioPlayer->mAndroidObjType has been set in android_audioPlayer_checkSourceSink()
137872042d4448cee63528c619537321ba73944c6382Glenn Kasten    // and if it was == INVALID_TYPE, then IEngine_CreateAudioPlayer would never call us
137972042d4448cee63528c619537321ba73944c6382Glenn Kasten    assert(INVALID_TYPE != pAudioPlayer->mAndroidObjType);
1380c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
138172042d4448cee63528c619537321ba73944c6382Glenn Kasten    // These initializations are in the same order as the field declarations in classes.h
138247550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten
138372042d4448cee63528c619537321ba73944c6382Glenn Kasten    // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
138472042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAndroidObjType: see above comment
138572042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1386213c31153b9bda7b5a091f2996da7b655c8ed451Glenn Kasten    pAudioPlayer->mSessionId = (audio_session_t) android::AudioSystem::newAudioUniqueId(
1387213c31153b9bda7b5a091f2996da7b655c8ed451Glenn Kasten            AUDIO_UNIQUE_ID_USE_SESSION);
1388143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    pAudioPlayer->mPIId = PLAYER_PIID_INVALID;
1389de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
139072042d4448cee63528c619537321ba73944c6382Glenn Kasten    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
139172042d4448cee63528c619537321ba73944c6382Glenn Kasten    // android::AudioSystem::acquireAudioSessionId(pAudioPlayer->mSessionId);
139283ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
139372042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
13948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
1395a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten
139667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    // mAudioTrack lifecycle is handled through mTrackPlayer
139767213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    pAudioPlayer->mTrackPlayer = new android::TrackPlayerBase();
139867213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    assert(pAudioPlayer->mTrackPlayer != 0);
139972042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
140072042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAPLayer
140172042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAuxEffect
1402e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
140372042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAuxSendLevel = 0;
140472042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
140572042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mDeferredStart = false;
14066d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
140772042d4448cee63528c619537321ba73944c6382Glenn Kasten    // This section re-initializes interface-specific fields that
140872042d4448cee63528c619537321ba73944c6382Glenn Kasten    // can be set or used regardless of whether the interface is
140972042d4448cee63528c619537321ba73944c6382Glenn Kasten    // exposed on the AudioPlayer or not
14106d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
141172042d4448cee63528c619537321ba73944c6382Glenn Kasten    switch (pAudioPlayer->mAndroidObjType) {
141272042d4448cee63528c619537321ba73944c6382Glenn Kasten    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
141372042d4448cee63528c619537321ba73944c6382Glenn Kasten        pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
141472042d4448cee63528c619537321ba73944c6382Glenn Kasten        pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
141572042d4448cee63528c619537321ba73944c6382Glenn Kasten        break;
141691145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
141791145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        pAudioPlayer->mPlaybackRate.mMinRate = MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE;
141891145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        pAudioPlayer->mPlaybackRate.mMaxRate = MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE;
141991145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        break;
142072042d4448cee63528c619537321ba73944c6382Glenn Kasten    default:
142172042d4448cee63528c619537321ba73944c6382Glenn Kasten        // use the default range
142272042d4448cee63528c619537321ba73944c6382Glenn Kasten        break;
142313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
142424430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi
1425773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
1426773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
1427a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1428a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
142975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
143075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        const void *pConfigValue, SLuint32 valueSize) {
143175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1432c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    SLresult result;
143375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1434c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
1435ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
143675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
143775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        // stream type
143875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
143975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1440c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_BUFFER_INSUFFICIENT;
144175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        } else {
144275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
144375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
14448c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
14458c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
14468c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // performance mode
14478c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) {
14488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
14498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_BUFFER_INSUFFICIENT;
14508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else {
14518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = audioPlayer_setPerformanceMode(ap, *(SLuint32*)pConfigValue);
14528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
145375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
145475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
145575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
145675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
145775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
145875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
145975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
146075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
146175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
146275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
146375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
146475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
146575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SLuint32* pValueSize, void *pConfigValue) {
146675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1467c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    SLresult result;
146875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1469c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    assert(NULL != ap && NULL != configKey && NULL != pValueSize);
1470ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
147175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
147275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        // stream type
1473c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        if (NULL == pConfigValue) {
1474c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_SUCCESS;
1475c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
147675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1477c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_BUFFER_INSUFFICIENT;
147875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        } else {
1479c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
148075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
1481c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
148275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
14838c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
14848c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
14858c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // performance mode
14868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if (NULL == pConfigValue) {
14878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_SUCCESS;
14888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) {
14898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
14908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_BUFFER_INSUFFICIENT;
14918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else {
14928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = audioPlayer_getPerformanceMode(ap, (SLuint32*)pConfigValue);
14938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
14948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE;
14958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
149675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
149775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
149875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
149975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
150075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
150175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
150275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
150375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
150475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
15058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioPlayer_realize for a PCM buffer queue player before creating the
15068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioTrack to determine which performance modes are allowed based on effect interfaces present
15078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePre(CAudioPlayer *pAudioPlayer)
15087880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten{
15098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL;
15107880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
151192e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten
151292e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten    // no need to check the buffer queue size, application side
151392e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten    // double-buffering (and more) is not a requirement for using fast tracks
15147880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
15157880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // Check a blacklist of interfaces that are incompatible with fast tracks.
15167880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // The alternative, to check a whitelist of compatible interfaces, is
15177880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // more maintainable but is too slow.  As a compromise, in a debug build
15187880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // we use both methods and warn if they produce different results.
15197880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // In release builds, we only use the blacklist method.
15207880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // If a blacklisted interface is added after realization using
15217880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // DynamicInterfaceManagement::AddInterface,
15227880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // then this won't be detected but the interface will be ineffective.
15237880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    static const unsigned blacklist[] = {
15247880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_BASSBOOST,
15257880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_EFFECTSEND,
15267880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ENVIRONMENTALREVERB,
15277880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_EQUALIZER,
15287880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PLAYBACKRATE,
15297880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PRESETREVERB,
15307880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_VIRTUALIZER,
15317880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDEFFECT,
15327880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDEFFECTSEND,
15337880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        // FIXME The problem with a blacklist is remembering to add new interfaces here
15347880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    };
15357880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
15367880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
15378c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            //TODO: query effect for EFFECT_FLAG_HW_ACC_xx flag to refine mode
15388c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            allowedModes &=
15398c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                    ~(ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS);
15407880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            break;
15417880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15427880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15437880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten#if LOG_NDEBUG == 0
15448c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    bool blacklistResult = (
15458c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            (allowedModes &
15468c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
15477880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    bool whitelistResult = true;
15487880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    static const unsigned whitelist[] = {
15497880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_BUFFERQUEUE,
15507880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_DYNAMICINTERFACEMANAGEMENT,
15517880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_METADATAEXTRACTION,
155278e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_MUTESOLO,
155378e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_OBJECT,
15547880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PLAY,
15557880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PREFETCHSTATUS,
155678e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_VOLUME,
15577880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDCONFIGURATION,
15587880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDSIMPLEBUFFERQUEUE,
15597880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDBUFFERQUEUESOURCE,
15607880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    };
15617880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
15627880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
15637880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            if (mph == whitelist[i]) {
15647880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                goto compatible;
15657880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            }
15667880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15677880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
15687880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            whitelistResult = false;
15697880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            break;
15707880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15717880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kastencompatible: ;
15727880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15737880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    if (whitelistResult != blacklistResult) {
15744e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGW("whitelistResult != blacklistResult");
15757880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15767880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten#endif
15778c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) {
15788c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) {
15798c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
15808c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
15818c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
15828c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) {
15838c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) {
15848c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
15858c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
15868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
15877880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten}
15887880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
15898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioPlayer_realize for a PCM buffer queue player after creating the
15908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioTrack to adjust performance mode based on actual output flags
15918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePost(CAudioPlayer *pAudioPlayer)
15928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent{
159367213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    audio_output_flags_t flags = pAudioPlayer->mTrackPlayer->mAudioTrack->getFlags();
15948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (pAudioPlayer->mPerformanceMode) {
15958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY:
15968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) ==
15978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) {
15988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
15998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
16018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        /* FALL THROUGH */
16028c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
16038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
16048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
16058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
16088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) == 0) {
16098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
16108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_NONE:
16138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
16148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
16168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
161775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
16187133228a478e16458b659946f2180ecddd13fda7Glenn Kasten// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
1619d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1620a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1621a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1622a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1623167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    AudioPlayback_Parameters app;
1624167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    app.sessionId = pAudioPlayer->mSessionId;
1625167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    app.streamType = pAudioPlayer->mStreamType;
1626167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1627a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
1628167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1629a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
1630a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
16314e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
16321fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-specific CAudioPlayer fields
16331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1634a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1635a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1636a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1637a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1638a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
16394e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        audio_channel_mask_t channelMask;
16404e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        channelMask = sles_to_audio_output_channel_mask(df_pcm->channelMask);
164128340d1d9199b789f0db015680b008c98084f0b7ilewis
164228340d1d9199b789f0db015680b008c98084f0b7ilewis        // To maintain backward compatibility with previous releases, ignore
164328340d1d9199b789f0db015680b008c98084f0b7ilewis        // channel masks that are not indexed.
164428340d1d9199b789f0db015680b008c98084f0b7ilewis        if (channelMask == AUDIO_CHANNEL_INVALID
164528340d1d9199b789f0db015680b008c98084f0b7ilewis                || audio_channel_mask_get_representation(channelMask)
164628340d1d9199b789f0db015680b008c98084f0b7ilewis                        == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
16474e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            channelMask = audio_channel_out_mask_from_count(df_pcm->numChannels);
164828340d1d9199b789f0db015680b008c98084f0b7ilewis            SL_LOGI("Emulating old channel mask behavior "
164928340d1d9199b789f0db015680b008c98084f0b7ilewis                    "(ignoring positional mask %#x, using default mask %#x based on "
165028340d1d9199b789f0db015680b008c98084f0b7ilewis                    "channel count of %d)", df_pcm->channelMask, channelMask,
165128340d1d9199b789f0db015680b008c98084f0b7ilewis                    df_pcm->numChannels);
16524e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
16534e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGV("AudioPlayer: mapped SLES channel mask %#x to android channel mask %#x",
16544e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            df_pcm->channelMask,
16554e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            channelMask);
16564e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
16578c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        checkAndSetPerformanceModePre(pAudioPlayer);
16588c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
16598daa09a2af477dbe495839ccf806919a02aa53cdEric Laurent        audio_output_flags_t policy;
16608c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        switch (pAudioPlayer->mPerformanceMode) {
16618c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
16628c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
16638c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16648c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_NONE:
16658c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_NONE;
16668c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16678c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
16688c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_FAST;
16698c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16708c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_LATENCY:
16718c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        default:
1672b4e379dd5a7dc764260ace7b73a782077ff10232Glenn Kasten            policy = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
16738c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16748c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16758c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
16768c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        int32_t notificationFrames;
16778c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((policy & AUDIO_OUTPUT_FLAG_FAST) != 0) {
16782ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            // negative notificationFrames is the number of notifications (sub-buffers) per track buffer
16792ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            // for details see the explanation at frameworks/av/include/media/AudioTrack.h
16802ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            notificationFrames = -pAudioPlayer->mBufferQueue.mNumBuffers;
16817880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        } else {
16822ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            notificationFrames = 0;
16837880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
16847880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
168567213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        android::AudioTrack* pat = new android::AudioTrack(
168675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                pAudioPlayer->mStreamType,                           // streamType
1687a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
1688e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung                sles_to_android_sampleFormat(df_pcm),                // format
16894e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                channelMask,                                         // channel mask
169078e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten                0,                                                   // frameCount
16917880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                policy,                                              // flags
1692a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                audioTrack_callBack_pullFromBuffQueue,               // callback
1693a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
1694f930011635e970346ca31d0509a173a695023f27Glenn Kasten                notificationFrames,                                  // see comment above
16957880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                pAudioPlayer->mSessionId);
169667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        android::status_t status = pat->initCheck();
1697337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        if (status != android::NO_ERROR) {
1698337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("AudioTrack::initCheck status %u", status);
16992dc0674aba6242c677365b675795773738397ab9Glenn Kasten            // FIXME should return a more specific result depending on status
17006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
170147550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            return result;
1702a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
17031fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
170467213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        pAudioPlayer->mTrackPlayer->init(pat, android::PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE,
170567213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                usageForStreamType(pAudioPlayer->mStreamType));
1706143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
17078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // update performance mode according to actual flags granted to AudioTrack
17088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        checkAndSetPerformanceModePost(pAudioPlayer);
17098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
17101fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-independent CAudioPlayer fields
17111fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
17121fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        pAudioPlayer->mNumChannels = df_pcm->numChannels;
1713a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
17143ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
1715f66b430471d691de4bf7b6bbc1a6527897f61cbdGlenn Kasten        // This use case does not have a separate "prepare" step
17163ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        pAudioPlayer->mAndroidObjState = ANDROID_READY;
171715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean
171815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        // If there is a JavaAudioRoutingProxy associated with this player, hook it up...
171915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        JNIEnv* j_env = NULL;
172015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        jclass clsAudioTrack = NULL;
172115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        jmethodID midRoutingProxy_connect = NULL;
172215f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        if (pAudioPlayer->mAndroidConfiguration.mRoutingProxy != NULL &&
172315f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (j_env = android::AndroidRuntime::getJNIEnv()) != NULL &&
172415f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (clsAudioTrack = j_env->FindClass("android/media/AudioTrack")) != NULL &&
172515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (midRoutingProxy_connect =
172615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                    j_env->GetMethodID(clsAudioTrack, "deferred_connect", "(J)V")) != NULL) {
172715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            j_env->ExceptionClear();
172815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            j_env->CallVoidMethod(pAudioPlayer->mAndroidConfiguration.mRoutingProxy,
172915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                                  midRoutingProxy_connect,
1730ebdc77a0a617a1112de28822de7219762d114294Paul McLean                                  (jlong)pAudioPlayer->mTrackPlayer->mAudioTrack.get());
173115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            if (j_env->ExceptionCheck()) {
1732143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                SL_LOGE("Java exception releasing player routing object.");
173315f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                result = SL_RESULT_INTERNAL_ERROR;
173467213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                pAudioPlayer->mTrackPlayer->mAudioTrack.clear();
1735677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                return result;
173615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            }
173713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
173815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean    }
173913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1740167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1741a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
1742a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
17434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD: {
17444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
17454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
1746ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi                        (void*)pAudioPlayer /*notifUSer*/);
17478a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
1748989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1749833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten            case SL_DATALOCATOR_URI: {
1750833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // The legacy implementation ran Stagefright within the application process, and
1751833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // so allowed local pathnames specified by URI that were openable by
1752833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // the application but were not openable by mediaserver.
1753833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // The current implementation runs Stagefright (mostly) within mediaserver,
1754833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // which runs as a different UID and likely a different current working directory.
1755833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // For backwards compatibility with any applications which may have relied on the
1756833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // previous behavior, we convert an openable file URI into an FD.
1757833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // Note that unlike SL_DATALOCATOR_ANDROIDFD, this FD is owned by us
1758833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // and so we close it as soon as we've passed it (via Binder dup) to mediaserver.
1759833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                const char *uri = (const char *)pAudioPlayer->mDataSource.mLocator.mURI.URI;
1760833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                if (!isDistantProtocol(uri)) {
1761833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // don't touch the original uri, we may need it later
1762833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    const char *pathname = uri;
1763833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // skip over an optional leading file:// prefix
1764833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    if (!strncasecmp(pathname, "file://", 7)) {
1765833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        pathname += 7;
1766833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    }
1767833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // attempt to open it as a file using the application's credentials
1768833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    int fd = ::open(pathname, O_RDONLY);
1769833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    if (fd >= 0) {
1770833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        // if open is successful, then check to see if it's a regular file
1771833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        struct stat statbuf;
1772833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        if (!::fstat(fd, &statbuf) && S_ISREG(statbuf.st_mode)) {
1773833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            // treat similarly to an FD data locator, but
1774833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            // let setDataSource take responsibility for closing fd
1775833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            pAudioPlayer->mAPlayer->setDataSource(fd, 0, statbuf.st_size, true);
1776833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            break;
1777833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        }
1778833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        // we were able to open it, but it's not a file, so let mediaserver try
1779833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        (void) ::close(fd);
1780833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    }
1781833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                }
1782833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // if either the URI didn't look like a file, or open failed, or not a file
1783833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                pAudioPlayer->mAPlayer->setDataSource(uri);
1784833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                } break;
1785989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            case SL_DATALOCATOR_ANDROIDFD: {
1786989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
17874ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                pAudioPlayer->mAPlayer->setDataSource(
1788989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1789989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
179097876858aa17c7f24c6a1d60be09a57bc1824ba3Jean-Michel Trivi                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1791989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
179213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                }
179313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                break;
1794989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            default:
17953ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1796989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                break;
1797989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
1798f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1799143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        if (pAudioPlayer->mObject.mEngine->mAudioManager == 0) {
1800143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            SL_LOGE("AudioPlayer realize: no audio service, player will not be registered");
1801143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = 0;
1802143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        } else {
1803143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = pAudioPlayer->mObject.mEngine->mAudioManager->trackPlayer(
1804143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    android::PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD,
180567213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                    usageForStreamType(pAudioPlayer->mStreamType), AUDIO_CONTENT_TYPE_UNKNOWN, 0);
1806143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        }
180713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
180813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1809167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
181013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
181113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // StreamPlayer
18124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
1813167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten        android::StreamPlayer* splr = new android::StreamPlayer(&app, false /*hasVideo*/,
18147133228a478e16458b659946f2180ecddd13fda7Glenn Kasten                &pAudioPlayer->mAndroidBufferQueue, pAudioPlayer->mCallbackProtector);
18157133228a478e16458b659946f2180ecddd13fda7Glenn Kasten        pAudioPlayer->mAPlayer = splr;
18167133228a478e16458b659946f2180ecddd13fda7Glenn Kasten        splr->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
181713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
181813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1819167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
182013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
182113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // AudioToCbRenderer
18224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
182313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
182413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        pAudioPlayer->mAPlayer = decoder;
1825bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the sink buffer queue
1826f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        decoder->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
1827bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the notifications coming from the SF code
182813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
182913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
183013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
183113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
183213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            decoder->setDataSource(
183313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
183413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
183513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD: {
183613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
183713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            decoder->setDataSource(
183813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
183913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
184013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
184113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                            (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
184213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
184313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
184413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
184513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
184613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
184713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
184813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
184913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
185013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1851167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1852fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //-----------------------------------
1853bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    // AacBqToPcmCbRenderer
1854bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
185570e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten        android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app,
185670e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten                &pAudioPlayer->mAndroidBufferQueue);
1857bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the sink buffer queue
1858f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        bqtobq->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
1859bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        pAudioPlayer->mAPlayer = bqtobq;
1860bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the notifications coming from the SF code,
1861bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
1862bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1863bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        }
1864bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        break;
1865167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1866bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    //-----------------------------------
1867a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
186813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1869337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
1870337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        break;
1871a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
1872a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1873677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent    if (result == SL_RESULT_SUCCESS) {
1874677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // proceed with effect initialization
1875677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // initialize EQ
1876677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // FIXME use a table of effect descriptors when adding support for more effects
1877677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent
1878677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // No session effects allowed even in latency with effects performance mode because HW
1879677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // accelerated effects are only tolerated as post processing in this mode
1880677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        if ((pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_PCM_BUFFERQUEUE) ||
1881677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                ((pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) &&
1882677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                 (pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS))) {
1883677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1884677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                    sizeof(effect_uuid_t)) == 0) {
1885677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1886677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1887677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1888677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            // initialize BassBoost
1889677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1890677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                    sizeof(effect_uuid_t)) == 0) {
1891677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1892677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1893677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1894677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            // initialize Virtualizer
1895677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1896677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                       sizeof(effect_uuid_t)) == 0) {
1897677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1898677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1899677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1900677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        }
1901f4aebfe499998c11b31319afb1c7738d4801f7b1Jean-Michel Trivi    }
19027e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi
19037e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi    // initialize EffectSend
19047e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi    // FIXME initialize EffectSend
19054be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
1906a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
1907a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
1908a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
190948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
191048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
191183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi/**
19124260ff7b8f65fdfe8d0176cdce66faf0a10c4b10Glenn Kasten * Called with a lock on AudioPlayer, and blocks until safe to destroy
191383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi */
191483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel TriviSLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
1915e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
191683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
191783ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
191822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    bool disableCallbacksBeforePreDestroy;
191922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    switch (pAudioPlayer->mAndroidObjType) {
192022ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // Not yet clear why this order is important, but it reduces detected deadlocks
192122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
192222ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        disableCallbacksBeforePreDestroy = true;
192322ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        break;
192422ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // Use the old behavior for all other use cases until proven
192522ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
192622ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    default:
192722ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        disableCallbacksBeforePreDestroy = false;
192822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        break;
192922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    }
1930f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten
193122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    if (disableCallbacksBeforePreDestroy) {
193222ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_unlock_exclusive(&pAudioPlayer->mObject);
193322ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        if (pAudioPlayer->mCallbackProtector != 0) {
193422ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten            pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
193522ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        }
193622ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_lock_exclusive(&pAudioPlayer->mObject);
1937f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    }
1938f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten
1939e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    if (pAudioPlayer->mAPlayer != 0) {
1940e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi        pAudioPlayer->mAPlayer->preDestroy();
1941e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    }
1942e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
1943e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi
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);
195083ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    }
195183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
195283ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    return result;
195383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi}
195483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
195583ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
195683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi//-----------------------------------------------------------------------------
1957d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
19586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
19599ab6dd04be11483a9e8b58de91228b17b821eca4Jean-Michel Trivi    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
19606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
19614ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
196267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: // intended fall-throughk, both types of players
196367213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                                           //   use the TrackPlayerBase for playback
1964143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
1965e49fde799fbeafee0d8ba905c1b7fbe4bc639cacJean-Michel Trivi        if (pAudioPlayer->mTrackPlayer != 0) {
1966e49fde799fbeafee0d8ba905c1b7fbe4bc639cacJean-Michel Trivi            pAudioPlayer->mTrackPlayer->destroy();
1967e49fde799fbeafee0d8ba905c1b7fbe4bc639cacJean-Michel Trivi        }
1968e49fde799fbeafee0d8ba905c1b7fbe4bc639cacJean-Michel Trivi
1969143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        // intended fall-through
19704ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
1971bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
1972bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
197313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        pAudioPlayer->mAPlayer.clear();
197413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
197513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
19766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
197713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1978337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
1979337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        break;
19806a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
19816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
198272042d4448cee63528c619537321ba73944c6382Glenn Kasten    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
198372042d4448cee63528c619537321ba73944c6382Glenn Kasten    // android::AudioSystem::releaseAudioSessionId(pAudioPlayer->mSessionId);
198483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
198567213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    pAudioPlayer->mTrackPlayer.clear();
198667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi
198772042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mCallbackProtector.clear();
1988989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi
1989a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    // explicit destructor
199067213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    pAudioPlayer->mTrackPlayer.~sp();
199147550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    // note that SetPlayState(PLAYING) may still hold a reference
19926cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    pAudioPlayer->mCallbackProtector.~sp();
1993f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi    pAudioPlayer->mAuxEffect.~sp();
199413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    pAudioPlayer->mAPlayer.~sp();
19954be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
19966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
19976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
19986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
19996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
20006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
20016d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn KastenSLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
20026d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        SLuint32 constraints) {
2003497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
2004ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20056d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
20066d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        // these asserts were already checked by the platform-independent layer
20076d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
20086d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten                (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
20096d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
2010497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // get the content sample rate
201124430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2012497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
201367213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        if (ap->mTrackPlayer->mAudioTrack != 0) {
201467213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
2015497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
2016497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
2017497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
201891145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD: {
201991145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        assert((MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
202091145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi                        (rate <= MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE));
20216d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
202291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        // apply the SL ES playback rate on the GenericPlayer
202391145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        if (ap->mAPlayer != 0) {
202491145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi            ap->mAPlayer->setPlaybackRate((int16_t)rate);
202591145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        }
202691145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        }
2027497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
20286d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
2029497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
2030337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
20316d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        result = SL_RESULT_FEATURE_UNSUPPORTED;
2032497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
2033497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
2034497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
2035497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
2036497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
2037497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
2038497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
20397f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
20407f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
20417f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
20427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pItemCount != NULL
20437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
20447f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
20457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
20467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
2047ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20487f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
204991540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
20507f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
20517f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
20527f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
20537f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            *pItemCount = decoder->getPcmFormatKeyCount();
20547f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
20557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20567f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
20577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        *pItemCount = 0;
20587f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
20607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return SL_RESULT_SUCCESS;
20617f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
20627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
20637f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
20647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
20657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
20667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
20677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
20687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pKeySize != NULL
20697f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
20707f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 *pKeySize) {
20717f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
20727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
20737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
20747f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2075ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20767f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
207791540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
20787f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
20797f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
20807f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
20817f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 keyNameSize = 0;
20827f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
20837f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
20847f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
20857f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // *pKeySize is the size of the region used to store the key name AND
20867f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                //   the information about the key (size, lang, encoding)
20877f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
20887f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
20897f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
20907f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20917f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
20927f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        *pKeySize = 0;
20937f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
20947f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20957f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
20967f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
20977f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
20987f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
20997f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21007f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21017f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21027f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21037f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21047f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pKey != NULL
21057f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
21067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
21077f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21087f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21097f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21107f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2111ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
21127f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
211391540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
21147f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
21157f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
21167f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
21177f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if ((size < sizeof(SLMetadataInfo) ||
21187f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
21197f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                            (char*)pKey->data)))) {
21207f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21217f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21227f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // successfully retrieved the key value, update the other fields
21237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pKey->encoding = SL_CHARACTERENCODING_UTF8;
21247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                memcpy((char *) pKey->langCountry, "en", 3);
21257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pKey->size = strlen((char*)pKey->data) + 1;
21267f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
21277f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
21287f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21297f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
21307f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
21317f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21327f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21337f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
21347f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
21357f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21367f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21377f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21387f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21397f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21407f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21417f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pValueSize != NULL
21427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
21437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 *pValueSize) {
21447f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21477f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2148ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
21497f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
215091540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
21517f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
21527f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
21537f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
21547f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 valueSize = 0;
21557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
21567f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21587f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // *pValueSize is the size of the region used to store the key value AND
21597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                //   the information about the value (size, lang, encoding)
21607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                *pValueSize = valueSize + sizeof(SLMetadataInfo);
21617f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
21627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
21637f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
21657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          *pValueSize = 0;
21667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          res = SL_RESULT_PARAMETER_INVALID;
21677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          break;
21687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21697f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
21707f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
21717f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21747f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21757f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21767f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21777f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pValue != NULL
21787f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
21797f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
21807f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21817f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21827f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21837f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2184ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
21857f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
218691540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
21877f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
21887f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
21897f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
21907f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            pValue->encoding = SL_CHARACTERENCODING_BINARY;
21917f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
21927f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 valueSize = 0;
21937f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if ((size < sizeof(SLMetadataInfo)
21947f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    || (!decoder->getPcmFormatValueSize(index, &valueSize))
21957f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
21967f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                            (SLuint32*)pValue->data)))) {
21977f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21987f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21997f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pValue->size = valueSize;
22007f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
22017f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
22027f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
22037f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
22047f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
22057f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
22067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
22077f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
22087f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
22097f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
22107f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
2211f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten// preconditions
2212f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  ap != NULL
2213f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  mutex is locked
2214f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  play state has changed
2215f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kastenvoid android_audioPlayer_setPlayState(CAudioPlayer *ap) {
22168a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
22178a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi    SLuint32 playState = ap->mPlay.mState;
22188a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
2219ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
22204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
22218a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        switch (playState) {
222248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
22233ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
222467213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->stop();
222548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
222648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
22273ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
222867213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->pause();
222948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
223048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
22313ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
223267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            if (ap->mTrackPlayer->mAudioTrack != 0) {
223367213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                // instead of ap->mTrackPlayer->mAudioTrack->start();
2234143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                if (!ap->mDeferredStart) {
2235143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    // state change
223667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi                    ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
2237143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                }
223847550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten                ap->mDeferredStart = true;
22393ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            }
224048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
224148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
2242e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
2243e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
224448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
224548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
224626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
2247143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
2248143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        switch (playState) {
2249143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
2250143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2251143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
2252143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2253143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
2254143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2255143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_PAUSED);
2256143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2257143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
2258143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
2259143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2260143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2261143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        }
2262143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        break;
2263143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
22644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
2265bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
2266bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
226713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // FIXME report and use the return code to the lock mechanism, which is where play state
226813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   changes are updated (see object_unlock_exclusive_attributes())
2269b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
227013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
227148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
227213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
227348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
227448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
227548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
227648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
22776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
22786a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
22795933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten// call when either player event flags, marker position, or position update period changes
2280bcfe680db1e392f3bb29382c2e15e89c3af783edGlenn Kastenvoid android_audioPlayer_usePlayEventMask(CAudioPlayer *ap) {
2281e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    IPlay *pPlayItf = &ap->mPlay;
2282e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 eventFlags = pPlayItf->mEventFlags;
2283ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    /*switch (ap->mAndroidObjType) {
22844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
22854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
22865933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (ap->mAPlayer != 0) {
228767213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        assert(ap->mTrackPlayer->mAudioTrack == 0);
22885933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
22895933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                (int32_t) pPlayItf->mPositionUpdatePeriod);
22905933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        return;
22915933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    }
22925933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
229367213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    if (ap->mTrackPlayer->mAudioTrack == 0) {
2294e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return;
22954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
22964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
22974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
229867213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        ap->mTrackPlayer->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
2299a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
23004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
23014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear marker
230267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        ap->mTrackPlayer->mAudioTrack->setMarkerPosition(0);
23034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
230667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi         ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(
230749e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
230849e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
23094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
23104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear periodic update
231167213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(0);
23124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
2315e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
23166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
23174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
23194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADMOVING
2320a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
232149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
23224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
2324e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
23254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
23286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
2331d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
2332dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2333ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
23344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
23364ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
23374ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int32_t durationMsec = ANDROID_UNKNOWN_TIME;
23384ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
23394ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->getDurationMsec(&durationMsec);
234013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
23414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
234213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
23434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
23444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
2346f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2347f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
23484ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default: {
234970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        *pDurMsec = SL_TIME_UNKNOWN;
23504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
2351dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
2352dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return SL_RESULT_SUCCESS;
2353dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi}
2354dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
2355dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
2356dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi//-----------------------------------------------------------------------------
2357d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
23586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2359ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
23604ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23614ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
236267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        if ((ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) || (ap->mTrackPlayer->mAudioTrack == 0)) {
2363a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = 0;
2364a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        } else {
23653ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            uint32_t positionInFrames;
236667213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->mAudioTrack->getPosition(&positionInFrames);
2367a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = ((int64_t)positionInFrames * 1000) /
2368a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2369a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        }
23706a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
23714ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23724ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
2373f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_URIFD:
2374f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2375f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
23764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int32_t posMsec = ANDROID_UNKNOWN_TIME;
23774ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
23784ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->getPositionMsec(&posMsec);
237943e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi        }
23804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
23816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
23824ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
23834ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default:
23854ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pPosMsec = 0;
23866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
23876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
23886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
2390b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten//-----------------------------------------------------------------------------
2391f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn KastenSLresult android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
2392f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
239343e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi
2394ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
23954ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23964ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
23974ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2398f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2399f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten        result = SL_RESULT_FEATURE_UNSUPPORTED;
24006f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24014ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
24034ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
24044ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
24054ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->seek(posMsec);
240643e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi        }
24076f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24084ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24094ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default:
24106f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24116f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    }
2412f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    return result;
24133c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi}
24143c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
24153c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
24163c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi//-----------------------------------------------------------------------------
2417f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn KastenSLresult android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
2418f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
2419d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2420f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2421f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_URIFD:
2422f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    // case AUDIOPLAY_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2423f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    //      would actually work, but what's the point?
2424f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
24254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        ap->mAPlayer->loop((bool)loopEnable);
2426f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      }
2427f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2428f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2429f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      result = SL_RESULT_FEATURE_UNSUPPORTED;
2430f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2431d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi    }
2432f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    return result;
2433d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi}
2434d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2435d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2436d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//-----------------------------------------------------------------------------
24374ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel TriviSLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
24384ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SLpermille threshold) {
24394ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
24404ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    switch (ap->mAndroidObjType) {
24424ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:
24434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
24444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
24454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
24464ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
24474ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24484ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default: {}
24494ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
24504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    return result;
24524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
24534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24554ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi//-----------------------------------------------------------------------------
245670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
2457a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
2458a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // queue was stopped when the queue become empty, we restart as soon as a new buffer
2459a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // has been enqueued since we're in playing state
246067213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi    if (ap->mTrackPlayer->mAudioTrack != 0) {
246167213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
246267213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        // instead of ap->mTrackPlayer->mAudioTrack->start();
246347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        ap->mDeferredStart = true;
2464b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi    }
2465a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
2466a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
2467a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // has received new data, signal it has sufficient data
2468b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten    if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
2469a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        // we wouldn't have been called unless we were previously in the underflow state
2470a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
2471a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        assert(0 == ap->mPrefetchStatus.mLevel);
2472a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2473a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        ap->mPrefetchStatus.mLevel = 1000;
2474a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        // callback or no callback?
2475a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
2476a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
2477a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
2478a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
2479a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
2480a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
2481a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        }
2482a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
2483b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi}
2484b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
2485b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
2486b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi//-----------------------------------------------------------------------------
24874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten/*
24884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten * BufferQueue::Clear
24894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten */
24900ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel TriviSLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
24914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
24924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
24930ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi    switch (ap->mAndroidObjType) {
24944b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    //-----------------------------------
24954b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    // AudioTrack
24964ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
249767213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi        if (ap->mTrackPlayer->mAudioTrack != 0) {
249867213e9075e0c51ed39142553facae586295dcaaJean-Michel Trivi            ap->mTrackPlayer->mAudioTrack->flush();
24990ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi        }
25004b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
25014b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    default:
25024b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
25034b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
25044b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
25054b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
25064b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    return result;
25074b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
2508b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
250926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
2510fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi//-----------------------------------------------------------------------------
2511be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivivoid android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
2512f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2513f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2514f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
2515e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2516e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        splr->appClear_l();
2517f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      } break;
2518f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2519f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      // nothing to do here, fall through
2520f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2521f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2522be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
2523be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
2524be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
252570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
2526f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2527f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2528f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
252970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2530bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi        splr->queueRefilled();
2531f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      } break;
2532f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2533f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      // FIXME this may require waking up the decoder if it is currently starved and isn't polling
2534f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2535f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2536be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
2537be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
2538