AudioPlayer_to_android.cpp revision 05ccff2aaa3e1507cdc7ab3b244c973c6708e009
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
23a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
2405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Triviinline SLuint32 android_to_sles_streamType(int type) {
2505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    return (SLuint32) type;
2605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
2705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
2805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------------------
2905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Triviinline int sles_to_android_streamType(SLuint32 type) {
3005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    return (int)type;
3105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
3205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
33a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline uint32_t sles_to_android_sampleRate(SLuint32 sampleRateMilliHertz) {
34a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (uint32_t)(sampleRateMilliHertz / 1000);
35a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
36a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
37a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_sampleFormat(SLuint32 pcmFormat) {
38a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pcmFormat) {
39a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_16:
40a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_16_BIT;
41a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
42a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_8:
43a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_8_BIT;
44a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
45a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_20:
46a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_24:
47a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_28:
48a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_32:
49a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        default:
50a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::INVALID_FORMAT;
51a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
52a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
53a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
54a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
55a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_channelMask(SLuint32 nbChannels, SLuint32 channelMask) {
56a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // FIXME handle channel mask mapping between SL ES and Android
57a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (nbChannels == 1 ?
58a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_MONO :
59a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_STEREO);
60a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
61a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
62a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
63a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviint android_getMinFrameCount(uint32_t sampleRate) {
64a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afSampleRate;
65a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
66a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
67a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
68a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
69a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afFrameCount;
70a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
71a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
72a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
73a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
74a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t afLatency;
75a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputLatency(&afLatency,
76a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
77a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
78a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
79a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
80a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
81a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (minBufCount < 2) minBufCount = 2;
82a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum number of frames to cover output latency at the sample rate of the content
83a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
846a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
861fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define LEFT_CHANNEL_MASK  0x1 << 0
871fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define RIGHT_CHANNEL_MASK 0x1 << 1
886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
89e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic void android_audioPlayerUpdateStereoVolume(CAudioPlayer* ap) {
906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    float leftVol = 1.0f, rightVol = 1.0f;
916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        return;
9445d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi    }
951fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // should not be used when muted
961fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (SL_BOOLEAN_TRUE == ap->mMute) {
971fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        return;
981fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1001fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int channelCount = ap->mNumChannels;
1011fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1021fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // mute has priority over solo
1031fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int leftAudibilityFactor = 1, rightAudibilityFactor = 1;
1041fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
105e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (channelCount >= STEREO_CHANNELS) {
106b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
1071fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left muted
1081fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            leftAudibilityFactor = 0;
1091fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
1101fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left not muted
111b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1121fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left soloed
1131fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                leftAudibilityFactor = 1;
1141fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
1151fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left not soloed
116b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
1171fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // right solo silences left
1181fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 0;
1191fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
1201fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and left is not muted
1211fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 1;
1221fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
1231fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
1241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
1251fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
126b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
1271fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right muted
1281fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            rightAudibilityFactor = 0;
1291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
1301fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right not muted
131b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
1321fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right soloed
1331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                rightAudibilityFactor = 1;
1341fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
1351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right not soloed
136b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1371fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left solo silences right
1381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 0;
1391fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
1401fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and right is not muted
1411fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 1;
1421fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
1431fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
1441fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
1451fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
1466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
1486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // amplification from volume level
1506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME use the FX Framework conversions
151e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    ap->mAmplFromVolLevel = pow(10, (float)ap->mVolume.mLevel/2000);
152e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    leftVol *= ap->mAmplFromVolLevel;
153e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    rightVol *= ap->mAmplFromVolLevel;
154a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
155f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    // amplification from stereo position
1561fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (ap->mVolume.mEnableStereoPosition) {
157f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // panning law depends on number of channels of content: stereo panning vs 2ch. balance
15845d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi        if(1 == channelCount) {
159f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo panning
1601fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
161e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[0] = cos(theta);
162e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[1] = sin(theta);
163f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
164f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo balance
1651fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            if (ap->mVolume.mStereoPosition > 0) {
166e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f;
167e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = 1.0f;
1686a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
169e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = 1.0f;
170e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f;
1716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
1726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
173e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        leftVol  *= ap->mAmplFromStereoPos[0];
174e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        rightVol *= ap->mAmplFromStereoPos[1];
175f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
176f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor);
1784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
1814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackMarker(CAudioPlayer* ap) {
1824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    //fprintf(stdout, "received event EVENT_MARKER from AudioTrack\n");
1834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1864614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
1924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
1934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
1944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
1954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
1984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackNewPos(CAudioPlayer* ap) {
1994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    //fprintf(stdout, "received event EVENT_NEW_POS from AudioTrack\n");
2004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
2014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
2024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
2044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
2054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
2064614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
2074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
2094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
2104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
2114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
2124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
2134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
2164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackUnderrun(CAudioPlayer* ap) {
2174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
2184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
2194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
2214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
2224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
2234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
2244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
2254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if ((NULL != callback) && headStalled) {
2274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
228f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
229f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi}
230f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
231f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi//-----------------------------------------------------------------------------
232de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
233de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi// from a URI, for prefetching events
234de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivistatic void android_prefetchEventCallback(const int event, const int data1, void* user) {
235de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL == user) {
236de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        return;
237de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
238f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
239de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
240de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    //fprintf(stdout, "received event %d = %d from SfAudioPlayer\n", event, data1);
241de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    switch(event) {
242f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
243de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchFillLevelUpdate): {
244de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME implement buffer filler level updates
245de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        fprintf(stderr, "[ FIXME implement buffer filler level updates ]\n");
246de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //ap->mPrefetchStatus.mLevel = ;
247de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
248de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
249de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchStatusChange): {
25006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        slPrefetchCallback callback = NULL;
251de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void* callbackPContext = NULL;
252de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
253de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_lock_exclusive(&ap->mPrefetchStatus);
254de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
255de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
256de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
257de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
2584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (data1 >= android::SfPlayer::kStatusIntermediate) {
259de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 1000;
2624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAndroidObjState = ANDROID_READY;
2634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        } else if (data1 < android::SfPlayer::kStatusIntermediate) {
264de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
2654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 0;
267de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
268de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_unlock_exclusive(&ap->mPrefetchStatus);
269de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
27006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (NULL != callback) {
271de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
27206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
273de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
274de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
275de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventEndOfStream): {
276de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        slPlayCallback playCallback = NULL;
277de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void * playContext = NULL;
278de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPlayItf callback or no callback?
279de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_lock_exclusive(&ap->mPlay);
280de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
281de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            playCallback = ap->mPlay.mCallback;
282de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            playContext = ap->mPlay.mContext;
28306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
284de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
285de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME update play position to make sure it's at the same value
286de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //       as getDuration if it's known?
287de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_unlock_exclusive(&ap->mPlay);
288de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
289de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (NULL != playCallback) {
290de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
29106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
2924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->stop();
293de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
294de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
2956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
2966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
2976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
298a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
299a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
300a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
301acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult sles_to_android_checkAudioPlayerSourceSink(CAudioPlayer *pAudioPlayer)
302c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
303acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
304acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
305c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
306c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Sink check:
307c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //     currently only OutputMix sinks are supported, regardless of the data source
308c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
309c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        fprintf(stderr, "Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX\n");
310c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
311c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
3126fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    // FIXME verify output mix is in realized state
313de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    fprintf(stderr, "[ FIXME verify OutputMix is in Realized state ]\n");
314c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
315c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
316c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
317c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
318c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
319c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 numBuffers = 0;
320c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
321c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
322c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
323c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE: {
324c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
325c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        numBuffers = dl_bq->numBuffers;
326c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (0 == numBuffers) {
327c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "Cannot create audio player: data source buffer queue has ");
328c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "a depth of 0");
329c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
330c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
331c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
332c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        switch (formatType) {
333a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
334c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
335c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
336c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->numChannels) {
337c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 1:
338c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 2:
339c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
340c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
341c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: implementation doesn't ");
342c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "support buffers with more than 2 channels");
343c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
344c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
345c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->samplesPerSec) {
346c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_8:
347c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_11_025:
348c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_12:
349c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_16:
350c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_22_05:
351c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_24:
352c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_32:
353c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_44_1:
354c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
355c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
356c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
357c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample rate");
358c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
359c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
360c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->bitsPerSample) {
361c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_8:
362f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                fprintf(stdout, "FIXME handle 8bit data\n");
363c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_16:
364c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
365c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
366c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
367c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample format %lu",
368c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                        (SLuint32)df_pcm->bitsPerSample);
369c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
370c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
371c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->containerSize) {
372c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 16:
373c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
374c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
375c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
376c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
377c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
378c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
379c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->channelMask) {
380c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // FIXME needs work
381c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
382c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
383c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
384c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->endianness) {
385c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_BYTEORDER_LITTLEENDIAN:
386c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
387c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others esp. big and native (new not in spec)
388c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
389c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
390c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
391c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
392c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
393c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
394c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
395c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
3966fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
397c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
398c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
3996fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
400c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
401c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // switch (formatType)
402acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten        pAudioPlayer->mBufferQueue.mNumBuffers = numBuffers;
403c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // case SL_DATALOCATOR_BUFFERQUEUE
404c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
405c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
4066fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
4076fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
4086fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
4096fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
4106fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            if (NULL == dl_uri->URI) {
4116fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_PARAMETER_INVALID;
4126fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            }
4136fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            // URI format
4146fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            switch (formatType) {
4156fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_MIME:
4166fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                break;
4176fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_PCM:
4186fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_RESERVED3:
4196fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_URI data source without SL_DATAFORMAT_MIME format\n");
4206fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
4216fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            } // switch (formatType)
4226fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
4236fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
4246fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
425c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
426c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
427c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
428c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
429c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED5:
430c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
431c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED8:
432c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
433c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
434c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
435c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
436c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
437c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
438c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
439c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
440773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
4414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
4434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivistatic void android_uriAudioTrackCallback(int event, void* user, void *info) {
4444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // EVENT_MORE_DATA needs to be handled with priority over the other events
4454614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // because it will be called the most often during playback
4464614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (event == android::AudioTrack::EVENT_MORE_DATA) {
4474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //fprintf(stderr, "received event EVENT_MORE_DATA from AudioTrack\n");
4484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // set size to 0 to signal we're not using the callback to write more data
4494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4504614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pBuff->size = 0;
4514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else if (NULL != user) {
4524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        switch (event) {
4534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_MARKER) :
4544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackMarker((CAudioPlayer *)user);
4554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_NEW_POS) :
4574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackNewPos((CAudioPlayer *)user);
4584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_UNDERRUN) :
4604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackUnderrun((CAudioPlayer *)user);
4614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        }
4624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
465a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
4661ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
4671ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// from a buffer queue.
4681ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivistatic void android_pullAudioTrackCallback(int event, void* user, void *info) {
4696a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *pAudioPlayer = (CAudioPlayer *)user;
4708f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi    void * callbackPContext = NULL;
4716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(event) {
4726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
4736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_MORE_DATA) : {
4746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //fprintf(stdout, "received event EVENT_MORE_DATA from AudioTrack\n");
4753a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        slBufferQueueCallback callback = NULL;
4761ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4771ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
4788f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        interface_lock_exclusive(&pAudioPlayer->mBufferQueue);
4791ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        if (pAudioPlayer->mBufferQueue.mState.count != 0) {
4801ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            //fprintf(stderr, "nbBuffers in queue = %lu\n",pAudioPlayer->mBufferQueue.mState.count);
4811ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            assert(pAudioPlayer->mBufferQueue.mFront != pAudioPlayer->mBufferQueue.mRear);
4821ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
483d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *oldFront = pAudioPlayer->mBufferQueue.mFront;
484d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *newFront = &oldFront[1];
4851ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
4861ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // FIXME handle 8bit based on buffer format
4871ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            short *pSrc = (short*)((char *)oldFront->mBuffer
4881ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    + pAudioPlayer->mBufferQueue.mSizeConsumed);
4891ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            if (pAudioPlayer->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
4901ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // can't consume the whole or rest of the buffer in one shot
4911ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed += pBuff->size;
4921ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // leave pBuff->size untouched
4931ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
4943a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
4951ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
4961ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
4971ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // finish consuming the buffer or consume the buffer in one shot
4981ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pBuff->size = oldFront->mSize - pAudioPlayer->mBufferQueue.mSizeConsumed;
4991ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed = 0;
5001ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5011ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
502d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten                        &pAudioPlayer->mBufferQueue.mArray[pAudioPlayer->mBufferQueue.mNumBuffers + 1])
5031ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
5041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    newFront = pAudioPlayer->mBufferQueue.mArray;
5051ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
5061ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mFront = newFront;
5071ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5081ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.count--;
5091ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.playIndex++;
5101ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5111ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
5123a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
5131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
5141ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5151ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // data has been consumed, and the buffer queue state has been updated
51606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi                // we will notify the client if applicable
5178f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi                callback = pAudioPlayer->mBufferQueue.mCallback;
5183a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // save callback data
5193a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                callbackPContext = pAudioPlayer->mBufferQueue.mContext;
5201ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
5211ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        } else {
5221ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // no data available
5231ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
5241ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
5258f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        interface_unlock_exclusive(&pAudioPlayer->mBufferQueue);
52606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        // notify client
5278f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        if (NULL != callback) {
5288f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi            (*callback)(&pAudioPlayer->mBufferQueue.mItf, callbackPContext);
5298f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        }
5306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
5316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
5321ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_MARKER) :
5344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackMarker(pAudioPlayer);
5354614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_NEW_POS) :
5384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackNewPos(pAudioPlayer);
5394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_UNDERRUN) :
5424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackUnderrun(pAudioPlayer);
5434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
5466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADATEND, SL_PLAYEVENT_HEADMOVING fit?
5476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
5481ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
5491ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
5501ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5511ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5521ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
553acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult sles_to_android_audioPlayerCreate(
55472a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten        CAudioPlayer *pAudioPlayer) {
555773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
556acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
557acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
558c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
559c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
560a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //--------------------------------------
561a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // Output check:
562c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // currently only OutputMix sinks are supported
563c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // this has been verified in sles_to_android_CheckAudioPlayerSourceSink
564c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
565c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
566c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
567c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
568c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
569a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
570a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   Buffer Queue to AudioTrack
571c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
5721ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL;
57306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
574497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
575c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
576a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
5776fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI to MediaPlayer
5783a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    case SL_DATALOCATOR_URI:
579c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = MEDIAPLAYER;
58006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
5814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
582c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
583c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
584c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
58506a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
586497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = 0;
587c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
588c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
589c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
590de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
5914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mAudioTrack = NULL;
5924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mSfPlayer.clear();
5934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mRenderLooper.clear();
594de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
595e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromVolLevel = 1.0f;
596e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
597e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
598e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
599c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return result;
600773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
601773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
602773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
603a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
604a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
6056fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel TriviSLresult sles_to_android_audioPlayerRealize(CAudioPlayer *pAudioPlayer, SLboolean async) {
606a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
607a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
6086fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //fprintf(stderr, "entering sles_to_android_audioPlayerRealize\n");
609a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
610a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
611a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
6126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
6131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
614a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        {
6151fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-specific CAudioPlayer fields
6161fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
617a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
618a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource;
619a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
620a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
621a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
622a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
623a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
6244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = new android::AudioTrack(
62505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                pAudioPlayer->mAndroidStreamType.mStreamType,        // streamType
626a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
627a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
628a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask
6291ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0,                                                   // frameCount (here min)
630a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                0,                                                   // flags
6311ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                android_pullAudioTrackCallback,                      // callback
632a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
6331ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0);  // FIXME find appropriate frame count         // notificationFrame
6344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (pAudioPlayer->mAudioTrack->initCheck() != android::NO_ERROR) {
6356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
636a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
6371fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-independent CAudioPlayer fields
6391fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6401fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        pAudioPlayer->mNumChannels = df_pcm->numChannels;
641de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
642a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
643a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
6446fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case MEDIAPLAYER: {
64580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
64680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        pAudioPlayer->mAndroidObjState = ANDROID_PREPARING;
647f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
648de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper = new android::ALooper();
649de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer = new android::SfPlayer(pAudioPlayer->mRenderLooper);
650de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer->setNotifListener(android_prefetchEventCallback,
651de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                (void*)pAudioPlayer /*notifUSer*/);
652de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->registerHandler(pAudioPlayer->mSfPlayer);
653de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->start(false /*runOnCallingThread*/);
654de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
6556fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi
6564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        int res = pAudioPlayer->mSfPlayer->prepare_sync(
657de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
658f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
659de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
6604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (SFPLAYER_SUCCESS != res) {
6614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
6621fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = 0;
663de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } else {
6644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // create audio track based on parameters retrieved from Stagefright
6654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAudioTrack = new android::AudioTrack(
66605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mAndroidStreamType.mStreamType,        // streamType
6674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getSampleRateHz(),          // sampleRate
6684614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    android::AudioSystem::PCM_16_BIT,                    // format
6694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getNumChannels() == 1 ?     //channel mask
6704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_MONO :
6714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_STEREO,
6724614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // frameCount (here min)
6734614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // flags
6744614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    android_uriAudioTrackCallback,                       // callback
6754614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    (void *) pAudioPlayer,                               // user
6764614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0);                                                  // notificationFrame
6771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = pAudioPlayer->mSfPlayer->getNumChannels();
6784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mSfPlayer->useAudioTrack(pAudioPlayer->mAudioTrack);
6794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
6804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (pAudioPlayer->mSfPlayer->wantPrefetch()) {
6814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_PREPARED;
6824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            } else {
6834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_READY;
6844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            }
6856fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
686de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
6874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
688de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
689a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
690a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
691a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
692a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
693a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
694a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
695a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
69605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------------------
69705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi/*
69805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * Called with a lock held on the CAudioPlayer
69905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi */
70005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel TriviSLresult sles_to_android_audioPlayerSetStreamType_l(CAudioPlayer *pAudioPlayer, SLuint32 type) {
70105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
70205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "sles_to_android_audioPlayerSetStreamType %lu\n", type);
70305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
70405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (pAudioPlayer->mAudioTrack == NULL) {
70505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        return SL_RESULT_RESOURCE_ERROR;
70605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
70705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (type == android_to_sles_streamType(pAudioPlayer->mAudioTrack->streamType())) {
70805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        return SL_RESULT_SUCCESS;
70905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
71005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
71105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    int format =  pAudioPlayer->mAudioTrack->format();
71205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    // FIXME sample rate should be cached
71305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    uint32_t sr = pAudioPlayer->mAudioTrack->getSampleRate();
71405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
71505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    pAudioPlayer->mAudioTrack->stop();
71605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    delete pAudioPlayer->mAudioTrack;
71705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    pAudioPlayer->mAudioTrack = new android::AudioTrack(
71805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    sles_to_android_streamType(type),               // streamType
71905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    sr,                                             // sampleRate
72005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    format,                                         // format
72105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mNumChannels== 1 ?                //channel mask
72205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_MONO :
72305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_STEREO,
72405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    0,                                              // frameCount (here min)
72505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    0,                                              // flags
72605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    pAudioPlayer->mAndroidObjType == MEDIAPLAYER ?  // callback
72705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                            android_uriAudioTrackCallback : android_pullAudioTrackCallback,
72805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    (void *) pAudioPlayer,                          // user
72905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi                    0);  // FIXME find appropriate frame count      // notificationFrame
73005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (pAudioPlayer->mAndroidObjType == MEDIAPLAYER) {
73105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        pAudioPlayer->mSfPlayer->useAudioTrack(pAudioPlayer->mAudioTrack);
73205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
73305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
73405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    return result;
73505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
73648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
73748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
7386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerDestroy(CAudioPlayer *pAudioPlayer) {
7396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
7406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //fprintf(stdout, "sles_to_android_audioPlayerDestroy\n");
7414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
7424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
7434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
7446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
7456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
7466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // AudioTrack
7476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
7486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
7496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
7506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
7516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // MediaPlayer
7526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
753f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // FIXME group in one function?
754de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (pAudioPlayer->mSfPlayer != NULL) {
7558bf87011ef453d8ce07c88dfac2d73063b7ecbedJean-Michel Trivi            pAudioPlayer->mSfPlayer->stop();
756de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mSfPlayer.clear();
757de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper->stop();
758de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper.clear();
7596fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
7606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
7616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
7626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
7636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
7646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (pAudioPlayer->mAudioTrack != NULL) {
7664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack->stop();
7674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        delete pAudioPlayer->mAudioTrack;
7684614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = NULL;
7694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
7704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
77106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    if (pAudioPlayer->mpLock != NULL) {
77206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        delete pAudioPlayer->mpLock;
77306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
77406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    }
77506a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi
7766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
7776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
7786a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7796a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7806a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
781497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
782497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerSetPlayRate(IPlaybackRate *pRateItf, SLpermille rate) {
783497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
784497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
785497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
786497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
7874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:
7884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER: {
789497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // get the content sample rate
790497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_lock_peek(ap);
791497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        uint32_t contentRate =
792497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            sles_to_android_sampleRate(ap->mDataSource.mFormat.mPCM.samplesPerSec);
793497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_unlock_peek(ap);
794497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
795497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->lock();
7964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (ap->mAudioTrack != NULL) {
7974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
798497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
799497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->unlock();
800497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
801497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
8024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
803497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
804497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
805497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
806497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
807497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
808497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
809497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
810497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
811497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
812497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
813497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerSetPlaybackRateBehavior(IPlaybackRate *pRateItf,
814497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 constraints) {
815497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
816497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
817497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
818497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
819497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
8204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER:
821497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
822497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            result = SL_RESULT_FEATURE_UNSUPPORTED;
823497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
824497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
825497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
826497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
827497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
828497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
829497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
830497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
831497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
832497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
833497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
834497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
835497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerGetCapabilitiesOfRate(IPlaybackRate *pRateItf,
836497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 *pCapabilities) {
837497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
838497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
839497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
840497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
841497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case MEDIAPLAYER:
8424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
843497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
844497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
845497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        *pCapabilities = 0;
846497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
847497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
848497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return SL_RESULT_SUCCESS;
849497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
850497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
851497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
852497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
853e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerSetPlayState(CAudioPlayer *ap) {
854e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 state = ap->mPlay.mState;
85548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    switch(ap->mAndroidObjType) {
85648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case AUDIOTRACK_PUSH:
8571ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
85848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        switch (state) {
85948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
86048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
8614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->stop();
86248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
86348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
86448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
8654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->pause();
86648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
86748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
86848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
8694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->start();
87048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
87148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
872e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
873e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
87448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
87548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
87648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case MEDIAPLAYER:
8776fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        switch (state) {
8781fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        case SL_PLAYSTATE_STOPPED: {
8796fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
8801fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            object_lock_peek(&ap);
8811fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
8821fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            object_unlock_peek(&ap);
8831fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            if (state >= ANDROID_READY) {
8841fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                ap->mAudioTrack->stop();
8851fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
8868bf87011ef453d8ce07c88dfac2d73063b7ecbedJean-Michel Trivi            ap->mSfPlayer->stop();
8871fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } break;
88880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PAUSED: {
8896fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
89080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
89180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
89280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
89380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            switch(state) {
89480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_UNINITIALIZED):
89580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARING):
89680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
89780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARED):
898de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    ap->mSfPlayer->startPrefetch_async();
899de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    break;
90080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREFETCHING):
90180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_READY):
90280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    // FIXME pause the actual playback
9034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    fprintf(stderr, "[ FIXME implement pause() ]\n");
90480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
90580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                default:
90680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
90780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            }
90880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
90980ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PLAYING: {
9106fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
91180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
91280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
91380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
91480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            if (state >= ANDROID_READY) {
9154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                ap->mAudioTrack->start();
916de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                ap->mSfPlayer->play();
91706a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi            }
91880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
9196fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        default:
920e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
921e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
9226fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
92348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
92448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
92548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
92648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
92748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
92848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
9296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
931e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerUseEventMask(CAudioPlayer *ap) {
932e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    IPlay *pPlayItf = &ap->mPlay;
933e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 eventFlags = pPlayItf->mEventFlags;
9344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    /*switch(ap->mAndroidObjType) {
9356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
9364614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:*/
9374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
939e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return;
9404614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
9434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
9444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      sample rate, verify if formula valid
9454614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      need to cache sample rate instead?
9464614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: fix marker computation due to sample rate reporting behavior ]\n");
9474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition((uint32_t)((pPlayItf->mMarkerPosition
9484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                * ap->mAudioTrack->getSampleRate())/1000));
9494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
9504614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear marker
9514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition(0);
9524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
9554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
9564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      sample rate, verify if formula valid
9574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: fix marker computation due to sample rate reporting behavior ]\n");
9584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(
9594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                (uint32_t)((pPlayItf->mPositionUpdatePeriod
9604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                        * ap->mAudioTrack->getSampleRate())/1000));
9614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
9624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear periodic update
9634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(0);
9644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
9674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (AUDIOTRACK_PULL == ap->mAndroidObjType) {
9686a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME support SL_PLAYEVENT_HEADATEND
969de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADATEND) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        } else if (MEDIAPLAYER == ap->mAndroidObjType) {
9714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
9726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
9736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
9744614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9754614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
9764614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADMOVING
9774614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
9804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADSTALLED
9814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADSTALLED) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9846a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
9856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
988dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel TriviSLresult sles_to_android_audioPlayerGetDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
989dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
990dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    switch(ap->mAndroidObjType) {
991dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PUSH:
992dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PULL:
993dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        *pDurMsec = SL_TIME_UNKNOWN;
994dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        // FIXME if the data source is not a buffer queue, and the audio data is saved in
995dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        //       shared memory with the mixer process, the duration is the size of the buffer
996dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        fprintf(stderr, "FIXME: sles_to_android_audioPlayerGetDuration() verify if duration can be retrieved\n");
997dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
998de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case MEDIAPLAYER: {
999de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        int64_t durationUsec = ap->mSfPlayer->getDurationUsec();
1000de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
1001de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
1002dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    default:
1003dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
1004dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
1005dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return SL_RESULT_SUCCESS;
1006dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi}
1007dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
1008dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
1009dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi//-----------------------------------------------------------------------------
1010e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerGetPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
10116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
10126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
10136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
10146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
10156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        uint32_t positionInFrames;
10164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->getPosition(&positionInFrames);
1017497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
1018497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        //      sample rate, verify if formula valid
1019497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        fprintf(stderr, "FIXME: fix marker computation due to sample rate reporting behavior");
10204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        *pPosMsec = positionInFrames * 1000 / ap->mAudioTrack->getSampleRate();
10216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
10226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
1023de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME implement getPosition
1024de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        fprintf(stderr, "FIXME: implement getPosition\n");
1025de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //ap->mMediaPlayerData.mMediaPlayer->getCurrentPosition((int*)pPosMsec);
10266a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
10276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
10286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
10296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
10306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
10316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
10326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1033b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten//-----------------------------------------------------------------------------
1034e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten/*
1035e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
1036e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * the IVolume interface.
1037e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Pre-condition:
1038e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten *   if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
1039e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten *   to sles_to_android_audioPlayerVolumeUpdate()
1040e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten */
1041e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic void android_audioPlayerSetMute(CAudioPlayer* ap) {
1042de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    android::AudioTrack *t = NULL;
1043b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    switch(ap->mAndroidObjType) {
1044b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PUSH:
1045b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PULL:
1046b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case MEDIAPLAYER:
10474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        t = ap->mAudioTrack;
1048b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
1049b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    default:
1050b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
10516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1052de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    // when unmuting: volume levels have already been updated in IVolume_SetMute
1053de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL != t) {
1054e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        t->mute(ap->mMute);
1055de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
1056e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten}
1057e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1058e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1059e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten//-----------------------------------------------------------------------------
1060e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn KastenSLresult sles_to_android_audioPlayerVolumeUpdate(CAudioPlayer* ap) {
1061e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    android_audioPlayerUpdateStereoVolume(ap);
1062e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    android_audioPlayerSetMute(ap);
10636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
10646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
1065