AudioPlayer_to_android.cpp revision b44084fdb096a2662085af0199b69ccb0dce5c30
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
17773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
18daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten#include "sles_allinclusive.h"
196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#include "math.h"
20f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi#include "utils/RefBase.h"
21773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
221ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
23a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi
2405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------------------
25a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviint android_getMinFrameCount(uint32_t sampleRate) {
26a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afSampleRate;
27a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
28a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
29a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
30a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
31a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afFrameCount;
32a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
33a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
34a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
35a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
36a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t afLatency;
37a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputLatency(&afLatency,
38a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
39a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
40a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
41a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
42a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
43a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (minBufCount < 2) minBufCount = 2;
44a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum number of frames to cover output latency at the sample rate of the content
45a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
48712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi
49712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi//-----------------------------------------------------------------------------
501fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define LEFT_CHANNEL_MASK  0x1 << 0
511fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define RIGHT_CHANNEL_MASK 0x1 << 1
526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
53d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivistatic void android_audioPlayer_updateStereoVolume(CAudioPlayer* ap) {
546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    float leftVol = 1.0f, rightVol = 1.0f;
556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        return;
5845d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi    }
591fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // should not be used when muted
601fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (SL_BOOLEAN_TRUE == ap->mMute) {
611fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        return;
621fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
641fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int channelCount = ap->mNumChannels;
651fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
661fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // mute has priority over solo
671fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int leftAudibilityFactor = 1, rightAudibilityFactor = 1;
681fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
69e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (channelCount >= STEREO_CHANNELS) {
70b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
711fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left muted
721fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            leftAudibilityFactor = 0;
731fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
741fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left not muted
75b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
761fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left soloed
771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                leftAudibilityFactor = 1;
781fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
791fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left not soloed
80b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
811fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // right solo silences left
821fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 0;
831fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
841fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and left is not muted
851fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 1;
861fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
871fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
881fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
891fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
90b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
911fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right muted
921fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            rightAudibilityFactor = 0;
931fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
941fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right not muted
95b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
961fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right soloed
971fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                rightAudibilityFactor = 1;
981fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
991fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right not soloed
100b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1011fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left solo silences right
1021fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 0;
1031fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
1041fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and right is not muted
1051fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 1;
1061fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
1071fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
1081fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
1091fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
1106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
1126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // amplification from volume level
1146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME use the FX Framework conversions
115e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    ap->mAmplFromVolLevel = pow(10, (float)ap->mVolume.mLevel/2000);
116e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    leftVol *= ap->mAmplFromVolLevel;
117e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    rightVol *= ap->mAmplFromVolLevel;
118a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
119f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    // amplification from stereo position
1201fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (ap->mVolume.mEnableStereoPosition) {
121f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // panning law depends on number of channels of content: stereo panning vs 2ch. balance
12245d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi        if(1 == channelCount) {
123f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo panning
1241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
125e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[0] = cos(theta);
126e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[1] = sin(theta);
127f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
128f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo balance
1291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            if (ap->mVolume.mStereoPosition > 0) {
130e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f;
131e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = 1.0f;
1326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
133e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = 1.0f;
134e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f;
1356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
1366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
137e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        leftVol  *= ap->mAmplFromStereoPos[0];
138e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        rightVol *= ap->mAmplFromStereoPos[1];
139f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
140f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1411fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor);
1424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
145e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
14649e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
1474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1504614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
1564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
1574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
1584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
1594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
162e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
16349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
1644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1684614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1724614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
1734614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
1744614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
1754614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
1764614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1774614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
180e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
1814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1864614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
1884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if ((NULL != callback) && headStalled) {
1914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
192f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
193f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi}
194f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
195e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi//-----------------------------------------------------------------------------
196e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi/**
197e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
198e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *
199e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
200e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       needs to be changed when the player reaches the end of the content to play. This is
201e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       relative to what the specification describes for buffer queues vs the
202e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
203e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
204e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          buffers in the queue, the playing of audio data stops. The player remains in the
205e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          SL_PLAYSTATE_PLAYING state."
206e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
207e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          of the current content and the player has paused."
208e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi */
209e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused) {
210e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    slPlayCallback playCallback = NULL;
211e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    void * playContext = NULL;
212e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    // SLPlayItf callback or no callback?
213e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    interface_lock_exclusive(&ap->mPlay);
214e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
215e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playCallback = ap->mPlay.mCallback;
216e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playContext = ap->mPlay.mContext;
217e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
218e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (setPlayStateToPaused) {
219e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
220e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
221e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    interface_unlock_exclusive(&ap->mPlay);
222e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    // callback with no lock held
223e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (NULL != playCallback) {
224e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
225e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
226e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi}
227e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
22814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
229f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi//-----------------------------------------------------------------------------
230de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
231e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi// from a URI or FD, for prefetching events
232de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivistatic void android_prefetchEventCallback(const int event, const int data1, void* user) {
233de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL == user) {
234de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        return;
235de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
236f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
237de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
23849e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event %d = %d from SfAudioPlayer", event, data1);
239de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    switch(event) {
240f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
241de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchFillLevelUpdate): {
242de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME implement buffer filler level updates
24349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        SL_LOGE("[ FIXME implement buffer filler level updates ]");
244de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //ap->mPrefetchStatus.mLevel = ;
245de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
246de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
247de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchStatusChange): {
24806a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        slPrefetchCallback callback = NULL;
249de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void* callbackPContext = NULL;
250de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
2515280fa9645cbf32efaf64021dc8a2d0ef50a3b22Glenn Kasten        // FIXME What if prefetch interface not explicitly requested by app? Can't assume it is there
252de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_lock_exclusive(&ap->mPrefetchStatus);
253de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
254de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
255de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
256de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
2574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (data1 >= android::SfPlayer::kStatusIntermediate) {
258de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 1000;
2614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAndroidObjState = ANDROID_READY;
2624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        } else if (data1 < android::SfPlayer::kStatusIntermediate) {
263de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
2644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 0;
266de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
267de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_unlock_exclusive(&ap->mPrefetchStatus);
268de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
26906a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (NULL != callback) {
270de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
27106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
272de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
273de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
274de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventEndOfStream): {
275e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/);
276de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME update play position to make sure it's at the same value
277de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //       as getDuration if it's known?
2784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->stop();
279de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
280de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
2816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
2826a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
2836a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
284a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
28514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
286a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
287a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
288d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
289c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
290acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
291acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
292c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
293c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Sink check:
294c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //     currently only OutputMix sinks are supported, regardless of the data source
295c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
29649e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        SL_LOGE("Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX");
297c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
298c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
299c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
300c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
301c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
302c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
303c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
3044b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
305c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
306c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
307c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
308c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE: {
309c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
3104b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
311c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
312c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        switch (formatType) {
313a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
314c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
315c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
316c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->numChannels) {
317c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 1:
318c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 2:
319c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
320c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
3214b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                // this should have already been rejected by checkDataFormat
3224b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported " \
3234b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
324c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
325c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
326c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->samplesPerSec) {
327c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_8:
328c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_11_025:
329c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_12:
330c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_16:
331c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_22_05:
332c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_24:
333c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_32:
334c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_44_1:
335c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
3364b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_SAMPLINGRATE_48:    // not 48?
3374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_SAMPLINGRATE_64:
3384b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_SAMPLINGRATE_88_2:
3394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_SAMPLINGRATE_96:
3404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_SAMPLINGRATE_192:
341c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
34249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
34349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                    (unsigned) df_pcm->samplesPerSec);
344c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
345c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
346c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->bitsPerSample) {
347c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_8:
3484b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                SL_LOGE("FIXME handle 8-bit data");
3494b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
350c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_16:
351c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
352c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
353c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
3544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                // this should have already been rejected by checkDataFormat
3554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported sample bit depth %lu",
356c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                        (SLuint32)df_pcm->bitsPerSample);
357c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
358c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
359c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->containerSize) {
360c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 16:
361c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
362c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
363c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
364c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
365c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
366c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
367c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->channelMask) {
368c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // FIXME needs work
369c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
370c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
371c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
372c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->endianness) {
373c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_BYTEORDER_LITTLEENDIAN:
374c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
3754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            case SL_BYTEORDER_BIGENDIAN:
3764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                SL_LOGE("FIXME big-endian byte order is unsupported");
3774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
3784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                // native is proposed but not yet in spec
379c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
3804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                SL_LOGE("Unsupported byte order %u", (unsigned) df_pcm->endianness);
381c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
382c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
383c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
384c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
385c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
386c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
38749e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGE("Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source "
38849e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "without SL_DATAFORMAT_PCM format");
389c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
390c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
39149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGE("Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source "
39249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "without SL_DATAFORMAT_PCM format");
393c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
394c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // switch (formatType)
395c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // case SL_DATALOCATOR_BUFFERQUEUE
396c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
397c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
3986fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
3996fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
4006fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
401989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
402989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        if (NULL == dl_uri->URI) {
403989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
404989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
405989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // URI format
406989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        switch (formatType) {
407989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
408989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
409989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_PCM:
410989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
41149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGE("Error: cannot create Audio Player with SL_DATALOCATOR_URI data source without "
41249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "SL_DATAFORMAT_MIME format");
413989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
414989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } // switch (formatType)
4156fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
4166fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
4176fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
418989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //   File Descriptor
419989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    case SL_DATALOCATOR_ANDROIDFD:
420989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        {
421989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // fd is already non null
422989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        switch (formatType) {
423989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
424989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
425989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_PCM:
426989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            // FIXME implement
42749e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGE("[ FIXME implement PCM FD data sources ]");
428989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
429989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
43049e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGE("Error: cannot create Audio Player with SL_DATALOCATOR_ANDROIDFD data source "
43149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
432989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
433989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } // switch (formatType)
434989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } // case SL_DATALOCATOR_ANDROIDFD
435989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        break;
436989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //------------------
437c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
438c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
439c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
440c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
441c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED5:
442c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
443c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED8:
444c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
445c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
446c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
447c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
448c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
449c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
450c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
451c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
452773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
4534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
455d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivistatic void audioTrack_callBack_uri(int event, void* user, void *info) {
4564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // EVENT_MORE_DATA needs to be handled with priority over the other events
4574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // because it will be called the most often during playback
4584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (event == android::AudioTrack::EVENT_MORE_DATA) {
45949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
4604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // set size to 0 to signal we're not using the callback to write more data
4614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pBuff->size = 0;
4634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else if (NULL != user) {
4644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        switch (event) {
4654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_MARKER) :
466e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                audioTrack_handleMarker_lockPlay((CAudioPlayer *)user);
4674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4684614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_NEW_POS) :
469e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                audioTrack_handleNewPos_lockPlay((CAudioPlayer *)user);
4704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_UNDERRUN) :
472e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                audioTrack_handleUnderrun_lockPlay((CAudioPlayer *)user);
473b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi                break;
474e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            default:
475e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
476e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                        (CAudioPlayer *)user);
477e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                break;
4784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        }
4794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
482a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
4831ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
4841ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// from a buffer queue.
485d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivistatic void audioTrack_callBack_pull(int event, void* user, void *info) {
486e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
4878f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi    void * callbackPContext = NULL;
4886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(event) {
4896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
4906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_MORE_DATA) : {
49149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
4923a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        slBufferQueueCallback callback = NULL;
4931ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4941ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
495e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_lock_exclusive(&ap->mBufferQueue);
496e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        if (ap->mBufferQueue.mState.count != 0) {
497e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count);
498e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
4991ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
500e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            BufferHeader *oldFront = ap->mBufferQueue.mFront;
501d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *newFront = &oldFront[1];
5021ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5031ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // FIXME handle 8bit based on buffer format
5041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            short *pSrc = (short*)((char *)oldFront->mBuffer
505e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                    + ap->mBufferQueue.mSizeConsumed);
506e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
5071ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // can't consume the whole or rest of the buffer in one shot
508e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mSizeConsumed += pBuff->size;
5091ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // leave pBuff->size untouched
5101ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
5113a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
5121ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
5131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
5141ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // finish consuming the buffer or consume the buffer in one shot
515e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
516e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mSizeConsumed = 0;
5171ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5181ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
519e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                        &ap->mBufferQueue.mArray
520e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                            [ap->mBufferQueue.mNumBuffers + 1])
5211ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
522e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                    newFront = ap->mBufferQueue.mArray;
5231ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
524e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mFront = newFront;
5251ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
526e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.count--;
527e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.playIndex++;
5281ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5291ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
5303a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
5311ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
5321ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5331ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // data has been consumed, and the buffer queue state has been updated
53406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi                // we will notify the client if applicable
535e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                callback = ap->mBufferQueue.mCallback;
5363a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // save callback data
537e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                callbackPContext = ap->mBufferQueue.mContext;
5381ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
539e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        } else { // empty queue
540e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal no data available
5411ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
542e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
543e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal we're at the end of the content, but don't pause (see note in function)
544e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/);
545e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
546e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // stop the track so it restarts playing faster when new data is enqueued
547e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            ap->mAudioTrack->stop();
5481ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
549e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_unlock_exclusive(&ap->mBufferQueue);
55006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        // notify client
5518f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        if (NULL != callback) {
552e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
5538f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        }
5546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
5556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
5561ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_MARKER) :
558e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleMarker_lockPlay(ap);
5594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_NEW_POS) :
562e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleNewPos_lockPlay(ap);
5634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_UNDERRUN) :
566e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleUnderrun_lockPlay(ap);
5674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5686a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5696a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
570e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
571b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
572b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi                (CAudioPlayer *)user);
5736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
5741ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
5751ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
5761ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5771ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5781ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
579d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_create(
58072a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten        CAudioPlayer *pAudioPlayer) {
581773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
582acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
583acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
584c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
585c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
586a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //--------------------------------------
587a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // Output check:
588c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // currently only OutputMix sinks are supported
589c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // this has been verified in sles_to_android_CheckAudioPlayerSourceSink
590c532e43aa9a0b3c84079f9dcb3a23490449b63cdJean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSnk->pLocator;
591c532e43aa9a0b3c84079f9dcb3a23490449b63cdJean-Michel Trivi    if (SL_DATALOCATOR_OUTPUTMIX == locatorType) {
5923d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten        // FIXME possible race between the earlier check and here - should atomically link these
593c532e43aa9a0b3c84079f9dcb3a23490449b63cdJean-Michel Trivi        // commented out to fix the build
594c532e43aa9a0b3c84079f9dcb3a23490449b63cdJean-Michel Trivi        //pAudioPlayer->mEffectSend->mOutputMix = pAudioSnk->pLocator->mOutputMix.outputMix;
5953d81b8ca5d3cee893672beb76e00849d4f3fa8b8Glenn Kasten    }
596c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
597c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
598c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
599c532e43aa9a0b3c84079f9dcb3a23490449b63cdJean-Michel Trivi    locatorType = *(SLuint32 *)pAudioSrc->pLocator;
600c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
601a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
602a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   Buffer Queue to AudioTrack
603c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
6041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL;
60506a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
606497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
607c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
608a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
609989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //   URI or FD to MediaPlayer
6103a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    case SL_DATALOCATOR_URI:
611989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    case SL_DATALOCATOR_ANDROIDFD:
612c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = MEDIAPLAYER;
61306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
6144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
615c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
616c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
617c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
61806a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
619497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = 0;
620c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
621c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
622c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
623de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
6244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mAudioTrack = NULL;
62514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
6264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mSfPlayer.clear();
6274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mRenderLooper.clear();
62814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
629de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
630e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromVolLevel = 1.0f;
631e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
632e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
633e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
634c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return result;
635773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
636773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
637773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
638a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
639a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
640d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
641a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
642a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
643b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi    SL_LOGV("pAudioPlayer=%p", pAudioPlayer);
644b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi
645a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
646a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
647a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
6486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
6491ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
650a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        {
6511fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-specific CAudioPlayer fields
6521fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
653a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
654a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource;
655a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
656a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
657a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
658a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
659a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
6604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = new android::AudioTrack(
66105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                pAudioPlayer->mAndroidStreamType.mStreamType,        // streamType
662a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
663a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
664a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask
6651ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0,                                                   // frameCount (here min)
666a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                0,                                                   // flags
667d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi                audioTrack_callBack_pull,                      // callback
668a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
6691ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0);  // FIXME find appropriate frame count         // notificationFrame
6704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (pAudioPlayer->mAudioTrack->initCheck() != android::NO_ERROR) {
6716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
672a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
6731fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6741fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-independent CAudioPlayer fields
6751fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6761fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        pAudioPlayer->mNumChannels = df_pcm->numChannels;
677a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
678de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
67914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
680a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
681a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
6826fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case MEDIAPLAYER: {
68380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
68480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        pAudioPlayer->mAndroidObjState = ANDROID_PREPARING;
685f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
686de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper = new android::ALooper();
687de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer = new android::SfPlayer(pAudioPlayer->mRenderLooper);
688de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer->setNotifListener(android_prefetchEventCallback,
689de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                (void*)pAudioPlayer /*notifUSer*/);
690de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->registerHandler(pAudioPlayer->mSfPlayer);
691de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->start(false /*runOnCallingThread*/);
692de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
6936fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi
694989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        int res;
695989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
696989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            case SL_DATALOCATOR_URI:
697989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                pAudioPlayer->mSfPlayer->setDataSource(
698989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
699989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                res = pAudioPlayer->mSfPlayer->prepare_sync();
700989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                break;
701989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            case SL_DATALOCATOR_ANDROIDFD: {
702989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
703989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                pAudioPlayer->mSfPlayer->setDataSource(
704989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
705989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
706989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                                (int64_t)SFPLAYER_FD_FIND_FILE_SIZE : offset,
707989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
708989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                res = pAudioPlayer->mSfPlayer->prepare_sync();
709989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                } break;
710989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            default:
711989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                res = ~SFPLAYER_SUCCESS;
712989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                break;
713989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
714f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
715de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
7164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (SFPLAYER_SUCCESS != res) {
7174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
7181fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = 0;
719a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            pAudioPlayer->mSampleRateMilliHz = 0;
720b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi            pAudioPlayer->mAudioTrack = NULL;
721de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } else {
7224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // create audio track based on parameters retrieved from Stagefright
7234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAudioTrack = new android::AudioTrack(
72405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mAndroidStreamType.mStreamType,        // streamType
7254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getSampleRateHz(),          // sampleRate
7264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    android::AudioSystem::PCM_16_BIT,                    // format
7274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getNumChannels() == 1 ?     //channel mask
7284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_MONO :
7294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_STEREO,
7304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // frameCount (here min)
7314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // flags
732d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi                    audioTrack_callBack_uri,                       // callback
7334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    (void *) pAudioPlayer,                               // user
7344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0);                                                  // notificationFrame
7351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = pAudioPlayer->mSfPlayer->getNumChannels();
736a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            pAudioPlayer->mSampleRateMilliHz =
737a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                    android_to_sles_sampleRate(pAudioPlayer->mSfPlayer->getSampleRateHz());
7384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mSfPlayer->useAudioTrack(pAudioPlayer->mAudioTrack);
7394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
7404614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (pAudioPlayer->mSfPlayer->wantPrefetch()) {
7414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_PREPARED;
7424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            } else {
7434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_READY;
7444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            }
7456fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
746de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
7474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
748de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
74914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
750a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
751a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
752a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
753a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
75414e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
755b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi
756b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi    if (ANDROID_UNINITIALIZED == pAudioPlayer->mAndroidObjState) {
757b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi        return result;
758b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi    }
759b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi    // proceed with effect initialization
760b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi
7614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    int sessionId = pAudioPlayer->mAudioTrack->getSessionId();
7624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // initialize EQ
7634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // FIXME use a table of effect descriptors when adding support for more effects
7644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
7654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            sizeof(effect_uuid_t)) == 0) {
7664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                android_eq_init(sessionId, pAudioPlayer);
7674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    }
7684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // initialize BassBoost
7694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // initialize PresetReverb
7704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // initialize EnvironmentalReverb + EffectSend
7714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // initialize Virtualizer
77214e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
7734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
774a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
775a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
776a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
77705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------------------
77805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi/*
77905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * Called with a lock held on the CAudioPlayer
78005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi */
781d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_setStreamType_l(CAudioPlayer *pAudioPlayer, SLuint32 type) {
78205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
78349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    SL_LOGV("android_audioPlayer_setStreamType %lu", type);
78405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
78505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (pAudioPlayer->mAudioTrack == NULL) {
78605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        return SL_RESULT_RESOURCE_ERROR;
78705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
78805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (type == android_to_sles_streamType(pAudioPlayer->mAudioTrack->streamType())) {
78905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        return SL_RESULT_SUCCESS;
79005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
79105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
79205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    int format =  pAudioPlayer->mAudioTrack->format();
79314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
7944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    int sessionId = pAudioPlayer->mAudioTrack->getSessionId();
79514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
796a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi    uint32_t sr = sles_to_android_sampleRate(pAudioPlayer->mSampleRateMilliHz);
79705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
79805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    pAudioPlayer->mAudioTrack->stop();
79905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    delete pAudioPlayer->mAudioTrack;
80005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    pAudioPlayer->mAudioTrack = new android::AudioTrack(
80105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    sles_to_android_streamType(type),               // streamType
80205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    sr,                                             // sampleRate
80305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    format,                                         // format
80405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mNumChannels== 1 ?                //channel mask
80505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_MONO :
80605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_STEREO,
80705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    0,                                              // frameCount (here min)
80805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    0,                                              // flags
80905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mAndroidObjType == MEDIAPLAYER ?  // callback
810d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi                            audioTrack_callBack_uri : audioTrack_callBack_pull,
81105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    (void *) pAudioPlayer,                          // user
81214e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten                    0    // FIXME find appropriate frame count      // notificationFrame
81314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
81414e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten                    , sessionId
81514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
81614e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten                    );
81714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
81805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (pAudioPlayer->mAndroidObjType == MEDIAPLAYER) {
81905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        pAudioPlayer->mSfPlayer->useAudioTrack(pAudioPlayer->mAudioTrack);
82005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
82114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
82205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
82305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    return result;
82405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
82548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
82648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
827d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
8286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
8299ab6dd04be11483a9e8b58de91228b17b821eca4Jean-Michel Trivi    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
8304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
8316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
8326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
8336a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // AudioTrack
8346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
8356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
8366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
83714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
8386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
8396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // MediaPlayer
8406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
841f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // FIXME group in one function?
842de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (pAudioPlayer->mSfPlayer != NULL) {
8439ab6dd04be11483a9e8b58de91228b17b821eca4Jean-Michel Trivi            pAudioPlayer->mRenderLooper->unregisterHandler(pAudioPlayer->mSfPlayer->id());
844de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mSfPlayer.clear();
845de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper->stop();
846de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper.clear();
8476fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
8486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
84914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
8506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
8516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
8526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
8536a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
8544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (pAudioPlayer->mAudioTrack != NULL) {
8554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack->stop();
8564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        delete pAudioPlayer->mAudioTrack;
8574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = NULL;
8584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
8594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
86006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    if (pAudioPlayer->mpLock != NULL) {
86106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        delete pAudioPlayer->mpLock;
86206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
86306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    }
86406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi
865989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
866989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi
86714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
8684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    pAudioPlayer->mEqualizer.mEqEffect.clear();
86914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
8704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
8716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
8726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
8736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
8746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
8756a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
876497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
877d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_setPlayRate(IPlaybackRate *pRateItf, SLpermille rate) {
878497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
879497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
880497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
881497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
8824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:
8834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER: {
884497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // get the content sample rate
885497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_lock_peek(ap);
886497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        uint32_t contentRate =
887497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            sles_to_android_sampleRate(ap->mDataSource.mFormat.mPCM.samplesPerSec);
888497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_unlock_peek(ap);
889497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
890497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->lock();
8914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (ap->mAudioTrack != NULL) {
8924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
893497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
894497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->unlock();
895497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
896497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
8974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
898497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
899497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
900497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
901497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
902497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
903497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
904497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
905497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
906497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
907497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
908d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_setPlaybackRateBehavior(IPlaybackRate *pRateItf,
909497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 constraints) {
910497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
911497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
912497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
913497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
914497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
9154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER:
916497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
917497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            result = SL_RESULT_FEATURE_UNSUPPORTED;
918497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
919497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
920497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
921497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
922497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
923497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
924497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
925497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
926497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
927497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
928497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
929497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
930d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_getCapabilitiesOfRate(IPlaybackRate *pRateItf,
931497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 *pCapabilities) {
932497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
933497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
934497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
935497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
936497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case MEDIAPLAYER:
9374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
938497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
939497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
940497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        *pCapabilities = 0;
941497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
942497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
943497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return SL_RESULT_SUCCESS;
944497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
945497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
946497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
947497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
948d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_setPlayState(CAudioPlayer *ap) {
949e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 state = ap->mPlay.mState;
95048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    switch(ap->mAndroidObjType) {
95148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case AUDIOTRACK_PUSH:
9521ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
95348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        switch (state) {
95448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
95549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
9564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->stop();
95748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
95848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
95949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
9604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->pause();
96148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
96248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
96349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
9644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->start();
96548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
96648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
967e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
968e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
96948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
97048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
97114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
97248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case MEDIAPLAYER:
9736fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        switch (state) {
9741fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        case SL_PLAYSTATE_STOPPED: {
97549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
9768bf87011ef453d8ce07c88dfac2d73063b7ecbedJean-Michel Trivi            ap->mSfPlayer->stop();
9771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } break;
97880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PAUSED: {
97949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
98080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
98180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
98280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
98380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            switch(state) {
98480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_UNINITIALIZED):
98580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARING):
9861c1c2d6d225e8180ba85f41170f7921d471308daJean-Michel Trivi                    ap->mSfPlayer->pause();
98780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
98880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARED):
989de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    ap->mSfPlayer->startPrefetch_async();
99080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREFETCHING):
99180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_READY):
9921c1c2d6d225e8180ba85f41170f7921d471308daJean-Michel Trivi                    ap->mSfPlayer->pause();
99380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
99480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                default:
99580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
99680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            }
99780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
99880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PLAYING: {
99949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
100080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
100180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
100280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
10031c1c2d6d225e8180ba85f41170f7921d471308daJean-Michel Trivi            // FIXME check in spec when playback is allowed to start in another state
100480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            if (state >= ANDROID_READY) {
1005de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                ap->mSfPlayer->play();
100606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi            }
100780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
10086fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        default:
1009e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
1010e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
10116fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
101248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
101314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
101448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
101548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
101648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
101748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
101848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
10196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
10206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
1021d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1022e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    IPlay *pPlayItf = &ap->mPlay;
1023e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 eventFlags = pPlayItf->mEventFlags;
10244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    /*switch(ap->mAndroidObjType) {
10256a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
10264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:*/
10274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
1029e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return;
10304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
10314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1033a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1034a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
10354614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
10364614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear marker
10374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition(0);
10384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
10394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10404614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
104149e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten         ap->mAudioTrack->setPositionUpdatePeriod(
104249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
104349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
10444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
10454614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear periodic update
10464614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(0);
10474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
10484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1050e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
10516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
10524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
10544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADMOVING
105549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        SL_LOGE("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
105649e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
10574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
10584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1059e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
10604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
10614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
10626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
10636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
10646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
10656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
1066d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
1067dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1068dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    switch(ap->mAndroidObjType) {
1069dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PUSH:
1070dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PULL:
1071dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        *pDurMsec = SL_TIME_UNKNOWN;
1072dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        // FIXME if the data source is not a buffer queue, and the audio data is saved in
1073dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        //       shared memory with the mixer process, the duration is the size of the buffer
107449e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        SL_LOGE("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved");
1075dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
107614e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
1077de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case MEDIAPLAYER: {
1078de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        int64_t durationUsec = ap->mSfPlayer->getDurationUsec();
1079de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
1080de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
108114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
1082dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    default:
1083dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
1084dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
1085dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return SL_RESULT_SUCCESS;
1086dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi}
1087dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
1088dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
1089dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi//-----------------------------------------------------------------------------
1090d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
10916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
10926a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
10936a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
10946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
10956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        uint32_t positionInFrames;
10964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->getPosition(&positionInFrames);
1097a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        if (ap->mSampleRateMilliHz == 0) {
1098a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = 0;
1099a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        } else {
1100a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = ((int64_t)positionInFrames * 1000) /
1101a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1102a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        }
11036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
11046a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
1105ea48d0be41dad9b380773343f0e23c6385351328Jean-Michel Trivi        *pPosMsec = ap->mSfPlayer->getPositionMsec();
11066a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
11076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
11086a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
11096a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
11106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
11116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
11126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1113b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten//-----------------------------------------------------------------------------
1114d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_seek(CAudioPlayer *pAudioPlayer, SLmillisecond posMsec) {
11156f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    switch(pAudioPlayer->mAndroidObjType) {
11166f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    case AUDIOTRACK_PUSH:
11176f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    case AUDIOTRACK_PULL:
11186f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
111914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#ifndef USE_BACKPORT
11206f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    case MEDIAPLAYER:
11216f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        pAudioPlayer->mSfPlayer->seek(posMsec);
11226f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
112314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#endif
11246f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    default:
11256f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
11266f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    }
11273c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi}
11283c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
11293c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
11303c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi//-----------------------------------------------------------------------------
1131e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten/*
1132e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
1133e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * the IVolume interface.
1134e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Pre-condition:
1135e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten *   if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
1136d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi *   to android_audioPlayer_volumeUpdate()
1137e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten */
1138d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivistatic void android_audioPlayer_setMute(CAudioPlayer* ap) {
1139de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    android::AudioTrack *t = NULL;
1140b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    switch(ap->mAndroidObjType) {
1141b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PUSH:
1142b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PULL:
1143b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case MEDIAPLAYER:
11444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        t = ap->mAudioTrack;
1145b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
1146b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    default:
1147b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
11486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1149de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    // when unmuting: volume levels have already been updated in IVolume_SetMute
1150de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL != t) {
1151e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        t->mute(ap->mMute);
1152de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
1153e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten}
1154e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1155e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1156e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten//-----------------------------------------------------------------------------
1157d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) {
1158d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi    android_audioPlayer_updateStereoVolume(ap);
1159d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi    android_audioPlayer_setMute(ap);
11606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
11616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
11624b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
11634b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
11644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten//-----------------------------------------------------------------------------
1165b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivivoid android_audioPlayer_forceAudioTrackStart(CAudioPlayer *ap) {
1166b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi    if (NULL != ap->mAudioTrack) {
1167b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi        ap->mAudioTrack->start();
1168b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi    }
1169b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi}
1170b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
1171b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
1172b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi//-----------------------------------------------------------------------------
11734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten/*
11744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten * BufferQueue::Clear
11754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten */
11764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn KastenSLresult android_audioPlayerClear(CAudioPlayer *pAudioPlayer) {
11774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
11784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
11794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    switch (pAudioPlayer->mAndroidObjType) {
11804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    //-----------------------------------
11814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    // AudioTrack
11824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    case AUDIOTRACK_PULL:
11834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    case AUDIOTRACK_PUSH:
11844b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        pAudioPlayer->mAudioTrack->flush();
11854b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
11864b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    default:
11874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
11884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
11894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
11904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
11914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    return result;
11924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
1193b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
1194