AudioPlayer_to_android.cpp revision b91e32605ecf39e34ad39936b1ee193bb4e30225
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//-----------------------------------------------------------------------------
24a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline uint32_t sles_to_android_sampleRate(SLuint32 sampleRateMilliHertz) {
25a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (uint32_t)(sampleRateMilliHertz / 1000);
26a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
27a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
28a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_sampleFormat(SLuint32 pcmFormat) {
29a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pcmFormat) {
30a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_16:
31a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_16_BIT;
32a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
33a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_8:
34a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_8_BIT;
35a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
36a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_20:
37a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_24:
38a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_28:
39a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_32:
40a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        default:
41a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::INVALID_FORMAT;
42a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
43a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
44a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
45a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
46a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_channelMask(SLuint32 nbChannels, SLuint32 channelMask) {
47a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // FIXME handle channel mask mapping between SL ES and Android
48a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (nbChannels == 1 ?
49a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_MONO :
50a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_STEREO);
51a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
52a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
53a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
54a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviint android_getMinFrameCount(uint32_t sampleRate) {
55a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afSampleRate;
56a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
57a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
58a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
59a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
60a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afFrameCount;
61a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
62a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
63a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
64a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
65a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t afLatency;
66a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputLatency(&afLatency,
67a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
68a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
69a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
70a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
71a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
72a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (minBufCount < 2) minBufCount = 2;
73a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum number of frames to cover output latency at the sample rate of the content
74a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
756a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define LEFT_CHANNEL_MASK  0x1 << 0
781fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi#define RIGHT_CHANNEL_MASK 0x1 << 1
796a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
80e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic void android_audioPlayerUpdateStereoVolume(CAudioPlayer* ap) {
816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    float leftVol = 1.0f, rightVol = 1.0f;
826a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        return;
8545d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi    }
861fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // should not be used when muted
871fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (SL_BOOLEAN_TRUE == ap->mMute) {
881fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        return;
891fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
911fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int channelCount = ap->mNumChannels;
921fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
931fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    // mute has priority over solo
941fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    int leftAudibilityFactor = 1, rightAudibilityFactor = 1;
951fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
96e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (channelCount >= STEREO_CHANNELS) {
97b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
981fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left muted
991fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            leftAudibilityFactor = 0;
1001fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
1011fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left not muted
102b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1031fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left soloed
1041fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                leftAudibilityFactor = 1;
1051fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
1061fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left not soloed
107b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
1081fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // right solo silences left
1091fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 0;
1101fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
1111fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and left is not muted
1121fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    leftAudibilityFactor = 1;
1131fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
1141fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
1151fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
1161fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
117b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
1181fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right muted
1191fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            rightAudibilityFactor = 0;
1201fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
1211fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right not muted
122b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
1231fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right soloed
1241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                rightAudibilityFactor = 1;
1251fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
1261fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right not soloed
127b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1281fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left solo silences right
1291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 0;
1301fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
1311fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and right is not muted
1321fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    rightAudibilityFactor = 1;
1331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
1341fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
1351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
1361fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
1376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
1396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
1406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // amplification from volume level
1416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME use the FX Framework conversions
142e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    ap->mAmplFromVolLevel = pow(10, (float)ap->mVolume.mLevel/2000);
143e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    leftVol *= ap->mAmplFromVolLevel;
144e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    rightVol *= ap->mAmplFromVolLevel;
145a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
146f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    // amplification from stereo position
1471fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    if (ap->mVolume.mEnableStereoPosition) {
148f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // panning law depends on number of channels of content: stereo panning vs 2ch. balance
14945d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi        if(1 == channelCount) {
150f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo panning
1511fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
152e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[0] = cos(theta);
153e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            ap->mAmplFromStereoPos[1] = sin(theta);
154f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
155f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo balance
1561fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            if (ap->mVolume.mStereoPosition > 0) {
157e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f;
158e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = 1.0f;
1596a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
160e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[0] = 1.0f;
161e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten                ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f;
1626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
1636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
164e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        leftVol  *= ap->mAmplFromStereoPos[0];
165e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        rightVol *= ap->mAmplFromStereoPos[1];
166f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
167f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1681fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor);
1694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
1724614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackMarker(CAudioPlayer* ap) {
1734614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    //fprintf(stdout, "received event EVENT_MARKER from AudioTrack\n");
1744614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1754614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1764614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1774614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1794614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1804614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1814614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
1834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
1844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
1854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
1864614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
1874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
1894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackNewPos(CAudioPlayer* ap) {
1904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    //fprintf(stdout, "received event EVENT_NEW_POS from AudioTrack\n");
1914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
1924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
1934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
1954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
1964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
1974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
1984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
2004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
2014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
2024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
2034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
2044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2064614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
2074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivivoid android_handleTrackUnderrun(CAudioPlayer* ap) {
2084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
2094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
2104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
2124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
2134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
2144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
2154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
2164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if ((NULL != callback) && headStalled) {
2184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
219f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
220f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi}
221f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
222f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi//-----------------------------------------------------------------------------
223de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
224de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi// from a URI, for prefetching events
225de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivistatic void android_prefetchEventCallback(const int event, const int data1, void* user) {
226de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL == user) {
227de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        return;
228de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
229f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
230de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
231de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    //fprintf(stdout, "received event %d = %d from SfAudioPlayer\n", event, data1);
232de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    switch(event) {
233f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
234de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchFillLevelUpdate): {
235de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME implement buffer filler level updates
236de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        fprintf(stderr, "[ FIXME implement buffer filler level updates ]\n");
237de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //ap->mPrefetchStatus.mLevel = ;
238de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
239de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
240de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventPrefetchStatusChange): {
24106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        slPrefetchCallback callback = NULL;
242de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void* callbackPContext = NULL;
243de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
244de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_lock_exclusive(&ap->mPrefetchStatus);
245de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
246de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
247de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
248de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
2494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (data1 >= android::SfPlayer::kStatusIntermediate) {
250de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 1000;
2534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAndroidObjState = ANDROID_READY;
2544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        } else if (data1 < android::SfPlayer::kStatusIntermediate) {
255de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
2564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // FIXME estimate fill level better?
2574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mPrefetchStatus.mLevel = 0;
258de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
259de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_unlock_exclusive(&ap->mPrefetchStatus);
260de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
26106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (NULL != callback) {
262de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
26306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
264de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
265de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
266de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case(android::SfPlayer::kEventEndOfStream): {
267de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        slPlayCallback playCallback = NULL;
268de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void * playContext = NULL;
269de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPlayItf callback or no callback?
270de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_lock_exclusive(&ap->mPlay);
271de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
272de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            playCallback = ap->mPlay.mCallback;
273de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            playContext = ap->mPlay.mContext;
27406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
275de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
276de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME update play position to make sure it's at the same value
277de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //       as getDuration if it's known?
278de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        interface_unlock_exclusive(&ap->mPlay);
279de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
280de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (NULL != playCallback) {
281de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
28206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
2834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->stop();
284de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
285de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
2866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
2876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
2886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
289a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
290a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
291a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
292acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult sles_to_android_checkAudioPlayerSourceSink(CAudioPlayer *pAudioPlayer)
293c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
294acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
295acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
296c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
297c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Sink check:
298c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //     currently only OutputMix sinks are supported, regardless of the data source
299c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
300c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        fprintf(stderr, "Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX\n");
301c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
302c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
3036fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    // FIXME verify output mix is in realized state
304de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    fprintf(stderr, "[ FIXME verify OutputMix is in Realized state ]\n");
305c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
306c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
307c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
308c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
309c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
310c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 numBuffers = 0;
311c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
312c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
313c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
314c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE: {
315c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
316c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        numBuffers = dl_bq->numBuffers;
317c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (0 == numBuffers) {
318c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "Cannot create audio player: data source buffer queue has ");
319c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "a depth of 0");
320c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
321c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
322c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
323c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        switch (formatType) {
324a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
325c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
326c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
327c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->numChannels) {
328c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 1:
329c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 2:
330c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
331c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
332c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: implementation doesn't ");
333c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "support buffers with more than 2 channels");
334c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
335c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
336c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->samplesPerSec) {
337c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_8:
338c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_11_025:
339c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_12:
340c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_16:
341c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_22_05:
342c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_24:
343c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_32:
344c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_44_1:
345c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
346c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
347c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
348c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample rate");
349c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
350c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
351c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->bitsPerSample) {
352c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_8:
353f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                fprintf(stdout, "FIXME handle 8bit data\n");
354c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_16:
355c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
356c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
357c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
358c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample format %lu",
359c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                        (SLuint32)df_pcm->bitsPerSample);
360c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
361c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
362c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->containerSize) {
363c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 16:
364c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
365c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
366c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
367c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
368c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
369c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
370c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->channelMask) {
371c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // FIXME needs work
372c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
373c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
374c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
375c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->endianness) {
376c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_BYTEORDER_LITTLEENDIAN:
377c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
378c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others esp. big and native (new not in spec)
379c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
380c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
381c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
382c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
383c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
384c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
385c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
386c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
3876fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
388c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
389c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
3906fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
391c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
392c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // switch (formatType)
393acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten        pAudioPlayer->mBufferQueue.mNumBuffers = numBuffers;
394c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // case SL_DATALOCATOR_BUFFERQUEUE
395c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
396c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
3976fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
3986fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
3996fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
4006fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
4016fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            if (NULL == dl_uri->URI) {
4026fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_PARAMETER_INVALID;
4036fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            }
4046fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            // URI format
4056fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            switch (formatType) {
4066fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_MIME:
4076fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                break;
4086fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_PCM:
4096fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_RESERVED3:
4106fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_URI data source without SL_DATAFORMAT_MIME format\n");
4116fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
4126fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            } // switch (formatType)
4136fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
4146fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
4156fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
416c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
417c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
418c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
419c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
420c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED5:
421c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
422c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED8:
423c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
424c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
425c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
426c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
427c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
428c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
429c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
430c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
431773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
4324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
4344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivistatic void android_uriAudioTrackCallback(int event, void* user, void *info) {
4354614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // EVENT_MORE_DATA needs to be handled with priority over the other events
4364614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    // because it will be called the most often during playback
4374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (event == android::AudioTrack::EVENT_MORE_DATA) {
4384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //fprintf(stderr, "received event EVENT_MORE_DATA from AudioTrack\n");
4394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // set size to 0 to signal we're not using the callback to write more data
4404614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4414614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pBuff->size = 0;
4424614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else if (NULL != user) {
4434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        switch (event) {
4444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_MARKER) :
4454614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackMarker((CAudioPlayer *)user);
4464614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_NEW_POS) :
4484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackNewPos((CAudioPlayer *)user);
4494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                break;
4504614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            case (android::AudioTrack::EVENT_UNDERRUN) :
4514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                android_handleTrackUnderrun((CAudioPlayer *)user);
4524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        }
4534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
456a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
4571ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
4581ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// from a buffer queue.
4591ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivistatic void android_pullAudioTrackCallback(int event, void* user, void *info) {
4606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *pAudioPlayer = (CAudioPlayer *)user;
4618f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi    void * callbackPContext = NULL;
4626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(event) {
4636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
4646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_MORE_DATA) : {
4656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //fprintf(stdout, "received event EVENT_MORE_DATA from AudioTrack\n");
4663a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        slBufferQueueCallback callback = NULL;
4671ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
4681ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
4698f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        interface_lock_exclusive(&pAudioPlayer->mBufferQueue);
4701ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        if (pAudioPlayer->mBufferQueue.mState.count != 0) {
4711ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            //fprintf(stderr, "nbBuffers in queue = %lu\n",pAudioPlayer->mBufferQueue.mState.count);
4721ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            assert(pAudioPlayer->mBufferQueue.mFront != pAudioPlayer->mBufferQueue.mRear);
4731ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
474d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *oldFront = pAudioPlayer->mBufferQueue.mFront;
475d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *newFront = &oldFront[1];
4761ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
4771ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // FIXME handle 8bit based on buffer format
4781ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            short *pSrc = (short*)((char *)oldFront->mBuffer
4791ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    + pAudioPlayer->mBufferQueue.mSizeConsumed);
4801ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            if (pAudioPlayer->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
4811ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // can't consume the whole or rest of the buffer in one shot
4821ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed += pBuff->size;
4831ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // leave pBuff->size untouched
4841ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
4853a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
4861ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
4871ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
4881ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // finish consuming the buffer or consume the buffer in one shot
4891ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pBuff->size = oldFront->mSize - pAudioPlayer->mBufferQueue.mSizeConsumed;
4901ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed = 0;
4911ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
4921ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
493d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten                        &pAudioPlayer->mBufferQueue.mArray[pAudioPlayer->mBufferQueue.mNumBuffers + 1])
4941ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
4951ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    newFront = pAudioPlayer->mBufferQueue.mArray;
4961ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
4971ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mFront = newFront;
4981ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
4991ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.count--;
5001ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.playIndex++;
5011ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5021ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
5033a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // FIXME can we avoid holding the lock during the copy?
5041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
5051ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5061ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // data has been consumed, and the buffer queue state has been updated
50706a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi                // we will notify the client if applicable
5088f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi                callback = pAudioPlayer->mBufferQueue.mCallback;
5093a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                // save callback data
5103a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten                callbackPContext = pAudioPlayer->mBufferQueue.mContext;
5111ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
5121ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        } else {
5131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // no data available
5141ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
5151ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
5168f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        interface_unlock_exclusive(&pAudioPlayer->mBufferQueue);
51706a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        // notify client
5188f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        if (NULL != callback) {
5198f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi            (*callback)(&pAudioPlayer->mBufferQueue.mItf, callbackPContext);
5208f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi        }
5216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
5226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
5231ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_MARKER) :
5254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackMarker(pAudioPlayer);
5264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_NEW_POS) :
5294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackNewPos(pAudioPlayer);
5304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case (android::AudioTrack::EVENT_UNDERRUN) :
5334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        android_handleTrackUnderrun(pAudioPlayer);
5344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
5356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
5376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADATEND, SL_PLAYEVENT_HEADMOVING fit?
5386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
5391ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
5401ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
5411ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5421ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
5431ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
544acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult sles_to_android_audioPlayerCreate(
54572a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten        CAudioPlayer *pAudioPlayer) {
546773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
547acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
548acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
549c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
550c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
551a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //--------------------------------------
552a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // Output check:
553c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // currently only OutputMix sinks are supported
554c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // this has been verified in sles_to_android_CheckAudioPlayerSourceSink
555c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
556c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
557c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
558c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
559c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
560a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
561a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   Buffer Queue to AudioTrack
562c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
5631ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL;
56406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
565497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
566c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
567a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
5686fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI to MediaPlayer
5693a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    case SL_DATALOCATOR_URI:
570c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = MEDIAPLAYER;
57106a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = new android::Mutex();
5724614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
573c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
574c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
575c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
57606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
577497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        pAudioPlayer->mPlaybackRate.mCapabilities = 0;
578c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
579c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
580c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
581de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
5824614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mAudioTrack = NULL;
5834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mSfPlayer.clear();
5844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mRenderLooper.clear();
585de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
586e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromVolLevel = 1.0f;
587e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
588e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
589e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
590c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return result;
591773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
592773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
593773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
594a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
595a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
5966fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel TriviSLresult sles_to_android_audioPlayerRealize(CAudioPlayer *pAudioPlayer, SLboolean async) {
597a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
598a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
5996fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //fprintf(stderr, "entering sles_to_android_audioPlayerRealize\n");
600a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
601a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
602a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
6036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
6041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
605a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        {
6061fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-specific CAudioPlayer fields
6071fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
608a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
609a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource;
610a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
611a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
612a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
613a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
614a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
6154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = new android::AudioTrack(
616a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                ANDROID_DEFAULT_OUTPUT_STREAM_TYPE,                  // streamType
617a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
618a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
619a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask
6201ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0,                                                   // frameCount (here min)
621a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                0,                                                   // flags
6221ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                android_pullAudioTrackCallback,                      // callback
623a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
6241ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0);  // FIXME find appropriate frame count         // notificationFrame
6254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (pAudioPlayer->mAudioTrack->initCheck() != android::NO_ERROR) {
6266a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
627a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
6281fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-independent CAudioPlayer fields
6301fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
6311fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        pAudioPlayer->mNumChannels = df_pcm->numChannels;
632de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
633a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
634a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
6356fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case MEDIAPLAYER: {
63680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
63780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        pAudioPlayer->mAndroidObjState = ANDROID_PREPARING;
638f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
639de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper = new android::ALooper();
640de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer = new android::SfPlayer(pAudioPlayer->mRenderLooper);
641de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mSfPlayer->setNotifListener(android_prefetchEventCallback,
642de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                (void*)pAudioPlayer /*notifUSer*/);
643de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->registerHandler(pAudioPlayer->mSfPlayer);
644de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        pAudioPlayer->mRenderLooper->start(false /*runOnCallingThread*/);
645de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
6466fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi
6474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        int res = pAudioPlayer->mSfPlayer->prepare_sync(
648de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
649f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
650de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_lock_exclusive(&pAudioPlayer->mObject);
6514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (SFPLAYER_SUCCESS != res) {
6524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
6531fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = 0;
654de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } else {
6554614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // create audio track based on parameters retrieved from Stagefright
6564614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mAudioTrack = new android::AudioTrack(
6574614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    ANDROID_DEFAULT_OUTPUT_STREAM_TYPE,                  // streamType
6584614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getSampleRateHz(),          // sampleRate
6594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    android::AudioSystem::PCM_16_BIT,                    // format
6604614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    pAudioPlayer->mSfPlayer->getNumChannels() == 1 ?     //channel mask
6614614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_MONO :
6624614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                            android::AudioSystem::CHANNEL_OUT_STEREO,
6634614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // frameCount (here min)
6644614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0,                                                   // flags
6654614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    android_uriAudioTrackCallback,                       // callback
6664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    (void *) pAudioPlayer,                               // user
6674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    0);                                                  // notificationFrame
6681fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            pAudioPlayer->mNumChannels = pAudioPlayer->mSfPlayer->getNumChannels();
6694614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            pAudioPlayer->mSfPlayer->useAudioTrack(pAudioPlayer->mAudioTrack);
6704614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
6714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (pAudioPlayer->mSfPlayer->wantPrefetch()) {
6724614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_PREPARED;
6734614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            } else {
6744614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                pAudioPlayer->mAndroidObjState = ANDROID_READY;
6754614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            }
6766fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
677de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        object_unlock_exclusive(&pAudioPlayer->mObject);
6784614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
679de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
680a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
681a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
682a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
683a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
684a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
685a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
686a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
68748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
68848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
6896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerDestroy(CAudioPlayer *pAudioPlayer) {
6906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
6916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //fprintf(stdout, "sles_to_android_audioPlayerDestroy\n");
6924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
6934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
6944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
6956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
6966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
6976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // AudioTrack
6986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
6996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
7006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
7016a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
7026a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // MediaPlayer
7036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
704f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        // FIXME group in one function?
705de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (pAudioPlayer->mSfPlayer != NULL) {
7068bf87011ef453d8ce07c88dfac2d73063b7ecbedJean-Michel Trivi            pAudioPlayer->mSfPlayer->stop();
707de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mSfPlayer.clear();
708de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper->stop();
709de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pAudioPlayer->mRenderLooper.clear();
7106fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
7116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
7126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
7136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
7146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
7156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (pAudioPlayer->mAudioTrack != NULL) {
7174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack->stop();
7184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        delete pAudioPlayer->mAudioTrack;
7194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        pAudioPlayer->mAudioTrack = NULL;
7204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
7214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
72206a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    if (pAudioPlayer->mpLock != NULL) {
72306a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        delete pAudioPlayer->mpLock;
72406a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        pAudioPlayer->mpLock = NULL;
72506a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi    }
72606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi
7276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
7286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
7296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
7316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
732497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
733497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerSetPlayRate(IPlaybackRate *pRateItf, SLpermille rate) {
734497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
735497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
736497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
737497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
7384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:
7394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER: {
740497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // get the content sample rate
741497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_lock_peek(ap);
742497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        uint32_t contentRate =
743497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            sles_to_android_sampleRate(ap->mDataSource.mFormat.mPCM.samplesPerSec);
744497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        object_unlock_peek(ap);
745497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
746497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->lock();
7474614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (ap->mAudioTrack != NULL) {
7484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
749497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
750497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        ap->mpLock->unlock();
751497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
752497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
7534614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
754497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
755497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
756497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
757497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
758497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
759497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
760497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
761497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
762497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
763497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
764497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerSetPlaybackRateBehavior(IPlaybackRate *pRateItf,
765497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 constraints) {
766497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
767497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
768497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
769497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
770497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
7714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case MEDIAPLAYER:
772497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
773497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi            result = SL_RESULT_FEATURE_UNSUPPORTED;
774497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
775497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
776497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
777497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
778497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
779497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
780497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
781497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
782497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
783497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
784497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
785497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi// called with no lock held
786497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel TriviSLresult sles_to_android_audioPlayerGetCapabilitiesOfRate(IPlaybackRate *pRateItf,
787497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        SLuint32 *pCapabilities) {
788497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pRateItf->mThis;
789497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    switch(ap->mAndroidObjType) {
790497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PUSH:
791497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case AUDIOTRACK_PULL:
792497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    case MEDIAPLAYER:
7934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
794497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
795497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
796497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        *pCapabilities = 0;
797497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
798497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
799497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return SL_RESULT_SUCCESS;
800497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
801497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
802497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
803497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
804e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerSetPlayState(CAudioPlayer *ap) {
805e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 state = ap->mPlay.mState;
80648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    switch(ap->mAndroidObjType) {
80748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case AUDIOTRACK_PUSH:
8081ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
80948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        switch (state) {
81048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
81148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
8124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->stop();
81348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
81448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
81548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
8164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->pause();
81748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
81848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
81948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
8204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->start();
82148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
82248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
823e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
824e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
82548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
82648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
82748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case MEDIAPLAYER:
8286fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        switch (state) {
8291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        case SL_PLAYSTATE_STOPPED: {
8306fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
8311fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            object_lock_peek(&ap);
8321fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
8331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            object_unlock_peek(&ap);
8341fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            if (state >= ANDROID_READY) {
8351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                ap->mAudioTrack->stop();
8361fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
8378bf87011ef453d8ce07c88dfac2d73063b7ecbedJean-Michel Trivi            ap->mSfPlayer->stop();
8381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } break;
83980ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PAUSED: {
8406fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
84180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
84280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
84380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
84480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            switch(state) {
84580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_UNINITIALIZED):
84680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARING):
84780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
84880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREPARED):
849de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    ap->mSfPlayer->startPrefetch_async();
850de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    break;
85180ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_PREFETCHING):
85280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                case(ANDROID_READY):
85380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    // FIXME pause the actual playback
8544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                    fprintf(stderr, "[ FIXME implement pause() ]\n");
85580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
85680ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                default:
85780ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi                    break;
85880ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            }
85980ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
86080ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi        case SL_PLAYSTATE_PLAYING: {
8616fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
86280ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_lock_peek(&ap);
86380ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            AndroidObject_state state = ap->mAndroidObjState;
86480ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            object_unlock_peek(&ap);
86580ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            if (state >= ANDROID_READY) {
8664614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                ap->mAudioTrack->start();
867de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                ap->mSfPlayer->play();
86806a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi            }
86980ed979fd2aef1d6bcaeb1bb2be5b220ac04fe9dJean-Michel Trivi            } break;
8706fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        default:
871e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
872e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
8736fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
87448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
87548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
87648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
87748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
87848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
87948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
8806a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
8816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
882e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerUseEventMask(CAudioPlayer *ap) {
883e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    IPlay *pPlayItf = &ap->mPlay;
884e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 eventFlags = pPlayItf->mEventFlags;
8854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    /*switch(ap->mAndroidObjType) {
8866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
8874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    case AUDIOTRACK_PULL:*/
8884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
8894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL == ap->mAudioTrack) {
890e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return;
8914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
8924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
8934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
8944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
8954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      sample rate, verify if formula valid
8964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      need to cache sample rate instead?
8974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: fix marker computation due to sample rate reporting behavior ]\n");
8984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition((uint32_t)((pPlayItf->mMarkerPosition
8994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                * ap->mAudioTrack->getSampleRate())/1000));
9004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
9014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear marker
9024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition(0);
9034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
9064614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
9074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        //      sample rate, verify if formula valid
9084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: fix marker computation due to sample rate reporting behavior ]\n");
9094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(
9104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                (uint32_t)((pPlayItf->mPositionUpdatePeriod
9114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                        * ap->mAudioTrack->getSampleRate())/1000));
9124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
9134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear periodic update
9144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(0);
9154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
9184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (AUDIOTRACK_PULL == ap->mAndroidObjType) {
9196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME support SL_PLAYEVENT_HEADATEND
920de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADATEND) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        } else if (MEDIAPLAYER == ap->mAndroidObjType) {
9224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
9236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
9246a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
9254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
9274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADMOVING
9284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
9314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADSTALLED
9324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        fprintf(stderr, "[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADSTALLED) on an SL_OBJECTID_AUDIOPLAYER to be implemented ]\n");
9334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
9344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
9356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
9366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
939dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel TriviSLresult sles_to_android_audioPlayerGetDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
940dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
941dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    switch(ap->mAndroidObjType) {
942dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PUSH:
943dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    case AUDIOTRACK_PULL:
944dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        *pDurMsec = SL_TIME_UNKNOWN;
945dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        // FIXME if the data source is not a buffer queue, and the audio data is saved in
946dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        //       shared memory with the mixer process, the duration is the size of the buffer
947dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        fprintf(stderr, "FIXME: sles_to_android_audioPlayerGetDuration() verify if duration can be retrieved\n");
948dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
949de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    case MEDIAPLAYER: {
950de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        int64_t durationUsec = ap->mSfPlayer->getDurationUsec();
951de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
952de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        } break;
953dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    default:
954dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        break;
955dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
956dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return SL_RESULT_SUCCESS;
957dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi}
958dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
959dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
960dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi//-----------------------------------------------------------------------------
961e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid sles_to_android_audioPlayerGetPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
9626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
9636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
9646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
9656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
9666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        uint32_t positionInFrames;
9674614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->getPosition(&positionInFrames);
968497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        //FIXME getSampleRate() returns the current playback sample rate, not the content
969497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        //      sample rate, verify if formula valid
970497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        fprintf(stderr, "FIXME: fix marker computation due to sample rate reporting behavior");
9714614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        *pPosMsec = positionInFrames * 1000 / ap->mAudioTrack->getSampleRate();
9726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
9736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
974de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // FIXME implement getPosition
975de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        fprintf(stderr, "FIXME: implement getPosition\n");
976de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        //ap->mMediaPlayerData.mMediaPlayer->getCurrentPosition((int*)pPosMsec);
9776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
9786a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
9796a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
9806a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
9816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
9826a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
9836a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
984b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten//-----------------------------------------------------------------------------
985e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten/*
986e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
987e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * the IVolume interface.
988e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten * Pre-condition:
989e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten *   if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
990e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten *   to sles_to_android_audioPlayerVolumeUpdate()
991e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten */
992e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic void android_audioPlayerSetMute(CAudioPlayer* ap) {
993de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    android::AudioTrack *t = NULL;
994b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    switch(ap->mAndroidObjType) {
995b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PUSH:
996b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PULL:
997b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case MEDIAPLAYER:
9984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        t = ap->mAudioTrack;
999b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
1000b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    default:
1001b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
10026a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1003de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    // when unmuting: volume levels have already been updated in IVolume_SetMute
1004de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL != t) {
1005e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        t->mute(ap->mMute);
1006de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
1007e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten}
1008e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1009e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
1010e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten//-----------------------------------------------------------------------------
1011e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn KastenSLresult sles_to_android_audioPlayerVolumeUpdate(CAudioPlayer* ap) {
1012e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    android_audioPlayerUpdateStereoVolume(ap);
1013e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    android_audioPlayerSetMute(ap);
10146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
10156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
1016