AudioPlayer_to_android.cpp revision 6fff2c605cdc46a10037e011d8fb47702ae70c37
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
18773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi#include "sles_to_android.h"
196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#include "math.h"
20773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
211ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
22a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
23a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline uint32_t sles_to_android_sampleRate(SLuint32 sampleRateMilliHertz) {
24a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (uint32_t)(sampleRateMilliHertz / 1000);
25a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
26a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
27a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_sampleFormat(SLuint32 pcmFormat) {
28a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pcmFormat) {
29a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_16:
30a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_16_BIT;
31a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
32a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_8:
33a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::PCM_8_BIT;
34a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            break;
35a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_20:
36a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_24:
37a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_28:
38a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        case SL_PCMSAMPLEFORMAT_FIXED_32:
39a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        default:
40a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return android::AudioSystem::INVALID_FORMAT;
41a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
42a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
43a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
44a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
45a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviinline int sles_to_android_channelMask(SLuint32 nbChannels, SLuint32 channelMask) {
46a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // FIXME handle channel mask mapping between SL ES and Android
47a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (nbChannels == 1 ?
48a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_MONO :
49a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            android::AudioSystem::CHANNEL_OUT_STEREO);
50a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
51a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
52a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
53a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Triviint android_getMinFrameCount(uint32_t sampleRate) {
54a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afSampleRate;
55a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
56a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
57a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
58a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
59a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    int afFrameCount;
60a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
61a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
62a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
63a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
64a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t afLatency;
65a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (android::AudioSystem::getOutputLatency(&afLatency,
66a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
67a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
68a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
69a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
70a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
71a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (minBufCount < 2) minBufCount = 2;
72a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // minimum number of frames to cover output latency at the sample rate of the content
73a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
756a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivivoid android_audioPlayerUpdateStereoVolume(IVolume *pVolItf) {
786a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // should not be used when muted
796a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (pVolItf->mMute) {
806a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        return;
816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
826a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    float leftVol = 1.0f, rightVol = 1.0f;
836a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
846a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //int muteSoloLeft, muteSoleRight;
856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pVolItf->mThis;
866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //muteSoloLeft = (mChannelMutes & CHANNEL_OUT_FRONT_LEFT) >> 2;
876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //muteSoloRight = (mChannelMutes & CHANNEL_OUT_FRONT_RIGHT) >> 3;
886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // amplification from volume level
926a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME use the FX Framework conversions
936a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    pVolItf->mAmplFromVolLevel = pow(10, (float)pVolItf->mLevel/2000);
946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    leftVol *= pVolItf->mAmplFromVolLevel;
956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    rightVol *= pVolItf->mAmplFromVolLevel;
96a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
1006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // amplification from stereo position
1016a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (pVolItf->mEnableStereoPosition) {
1026a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // panning law depends on number of channels of content: stereo panning vs 2ch. balance
1036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            if(ap->mAudioTrack->channelCount() == 1) {
1046a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                // stereo panning
1056a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                double theta = (1000+pVolItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
1066a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                pVolItf->mAmplFromStereoPos[0] = cos(theta);
1076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                pVolItf->mAmplFromStereoPos[1] = sin(theta);
1086a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
1096a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                // stereo balance
1106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                if (pVolItf->mStereoPosition > 0) {
1116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    pVolItf->mAmplFromStereoPos[0] = (1000-pVolItf->mStereoPosition)/1000.0f;
1126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    pVolItf->mAmplFromStereoPos[1] = 1.0f;
1136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                } else {
1146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    pVolItf->mAmplFromStereoPos[0] = 1.0f;
1156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    pVolItf->mAmplFromStereoPos[1] = (1000+pVolItf->mStereoPosition)/1000.0f;
1166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                }
1176a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
1186a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            leftVol  *= pVolItf->mAmplFromStereoPos[0];
1196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            rightVol *= pVolItf->mAmplFromStereoPos[1];
1206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
1216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        ap->mAudioTrack->setVolume(leftVol, rightVol);
1226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
1236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
1246a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        ap->mMediaPlayer->setVolume(leftVol, rightVol);
1256a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
1266a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
1276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
1286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
129a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
130a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
131a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
132a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
1336a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_checkAudioPlayerSourceSink(const SLDataSource *pAudioSrc,
1346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        const SLDataSink *pAudioSnk)
135c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
136c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
137c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Sink check:
138c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //     currently only OutputMix sinks are supported, regardless of the data source
139c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
140c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        fprintf(stderr, "Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX\n");
141c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
142c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
1436fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    // FIXME verify output mix is in realized state
1446fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    fprintf(stderr, "FIXME verify OutputMix is in Realized state\n");
145c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
146c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
147c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
148c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
149c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
150c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 numBuffers = 0;
151c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
152c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
153c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
154c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE: {
155c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
156c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        numBuffers = dl_bq->numBuffers;
157c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (0 == numBuffers) {
158c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "Cannot create audio player: data source buffer queue has ");
159c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            fprintf(stderr, "a depth of 0");
160c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
161c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
162c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
163c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        switch (formatType) {
164a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
165c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
166c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
167c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->numChannels) {
168c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 1:
169c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 2:
170c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
171c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
172c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: implementation doesn't ");
173c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "support buffers with more than 2 channels");
174c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
175c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
176c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->samplesPerSec) {
177c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_8:
178c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_11_025:
179c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_12:
180c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_16:
181c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_22_05:
182c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_24:
183c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_32:
184c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_SAMPLINGRATE_44_1:
185c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
186c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
187c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
188c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample rate");
189c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
190c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
191c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->bitsPerSample) {
192c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_8:
193c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_PCMSAMPLEFORMAT_FIXED_16:
194c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
195c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
196c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
197c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                fprintf(stderr, "Cannot create audio player: unsupported sample format %lu",
198c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                        (SLuint32)df_pcm->bitsPerSample);
199c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
200c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
201c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->containerSize) {
202c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case 16:
203c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
204c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others
205c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
206c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
207c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
208c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
209c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->channelMask) {
210c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // FIXME needs work
211c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
212c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
213c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
214c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            switch (df_pcm->endianness) {
215c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            case SL_BYTEORDER_LITTLEENDIAN:
216c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                break;
217c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // others esp. big and native (new not in spec)
218c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            default:
219c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                //FIXME add error message
220c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
221c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
222c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
223c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
224c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
225c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_RESERVED3:
2266fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
227c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
228c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
2296fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_BUFFERQUEUE data source without SL_DATAFORMAT_PCM format\n");
230c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
231c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // switch (formatType)
232c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } // case SL_DATALOCATOR_BUFFERQUEUE
233c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
234c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
2356fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
2366fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
2376fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
2386fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
2396fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            if (NULL == dl_uri->URI) {
2406fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_PARAMETER_INVALID;
2416fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            }
2426fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            // URI format
2436fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            switch (formatType) {
2446fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_MIME:
2456fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                break;
2466fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_PCM:
2476fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            case SL_DATAFORMAT_RESERVED3:
2486fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                fprintf(stderr, "Error: cannot create Audio Player with SL_DATALOCATOR_URI data source without SL_DATAFORMAT_MIME format\n");
2496fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
2506fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            } // switch (formatType)
2516fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
2526fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
2536fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
254c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
255c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
256c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
257c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
258c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED5:
259c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
260c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_RESERVED8:
261c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
262c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
263c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
264c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
265c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
266c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
267c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
268c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
269773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
270a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
2711ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
2721ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// from a buffer queue.
2731ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivistatic void android_pullAudioTrackCallback(int event, void* user, void *info) {
2746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *pAudioPlayer = (CAudioPlayer *)user;
2756a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(event) {
2766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
2776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_MORE_DATA) : {
2786a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //fprintf(stdout, "received event EVENT_MORE_DATA from AudioTrack\n");
2791ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
2801ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
2811ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
2821ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        //interface_lock_exclusive(&pAudioPlayer->mBufferQueue);
2831ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        if (pAudioPlayer->mBufferQueue.mState.count != 0) {
2841ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            //fprintf(stderr, "nbBuffers in queue = %lu\n",pAudioPlayer->mBufferQueue.mState.count);
2851ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            assert(pAudioPlayer->mBufferQueue.mFront != pAudioPlayer->mBufferQueue.mRear);
2861ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
2871ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            struct BufferHeader *oldFront = pAudioPlayer->mBufferQueue.mFront;
2881ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            struct BufferHeader *newFront = &oldFront[1];
2891ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
2901ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // FIXME handle 8bit based on buffer format
2911ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            short *pSrc = (short*)((char *)oldFront->mBuffer
2921ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    + pAudioPlayer->mBufferQueue.mSizeConsumed);
2931ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            if (pAudioPlayer->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
2941ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // can't consume the whole or rest of the buffer in one shot
2951ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed += pBuff->size;
2961ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // leave pBuff->size untouched
2971ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
2981ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
2991ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
3001ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // finish consuming the buffer or consume the buffer in one shot
3011ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pBuff->size = oldFront->mSize - pAudioPlayer->mBufferQueue.mSizeConsumed;
3021ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mSizeConsumed = 0;
3031ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3041ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
3051ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                        &pAudioPlayer->mBufferQueue.mArray[pAudioPlayer->mBufferQueue.mNumBuffers])
3061ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
3071ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                    newFront = pAudioPlayer->mBufferQueue.mArray;
3081ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
3091ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mFront = newFront;
3101ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3111ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.count--;
3121ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                pAudioPlayer->mBufferQueue.mState.playIndex++;
3131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3141ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // consume data
3151ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                memcpy (pBuff->i16, pSrc, pBuff->size);
3161ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3171ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // data has been consumed, and the buffer queue state has been updated
3181ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                // we can notify the client if applicable
3191ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                slBufferQueueCallback callback = pAudioPlayer->mBufferQueue.mCallback;
3201ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (NULL != callback) {
3211ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                     (*callback)(&pAudioPlayer->mBufferQueue.mItf,
3221ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                             pAudioPlayer->mBufferQueue.mContext);
3231ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                 }
3241ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
3251ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        } else {
3261ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            // no data available
3271ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
3281ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
3296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3301ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        //interface_unlock_exclusive(&pAudioPlayer->mBufferQueue);
3316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
3326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
3331ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_MARKER) : {
3356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //fprintf(stdout, "received event EVENT_MARKER from AudioTrack\n");
3366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        slPlayCallback callback = pAudioPlayer->mPlay.mCallback;
3386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (NULL != callback) {
3396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
3406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            (*callback)(&pAudioPlayer->mPlay.mItf, pAudioPlayer->mPlay.mContext,
3416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    SL_PLAYEVENT_HEADATMARKER);
3426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
3436a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
3456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
3466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
3476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_NEW_POS) : {
3486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //fprintf(stdout, "received event EVENT_NEW_POS from AudioTrack\n");
3496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        slPlayCallback callback = pAudioPlayer->mPlay.mCallback;
3516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (NULL != callback) {
3526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
3536a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            (*callback)(&pAudioPlayer->mPlay.mItf, pAudioPlayer->mPlay.mContext,
3546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    SL_PLAYEVENT_HEADATNEWPOS);
3556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
3566a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3576a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
3586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
3596a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
3606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case (android::AudioTrack::EVENT_UNDERRUN) : {
3616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        slPlayCallback callback = pAudioPlayer->mPlay.mCallback;
3636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if ((NULL != callback) && (pAudioPlayer->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED)) {
3646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            (*callback)(&pAudioPlayer->mPlay.mItf, pAudioPlayer->mPlay.mContext,
3656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    SL_PLAYEVENT_HEADSTALLED);
3666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
3676a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME locks: issue of callbacks calling callbacks without reentrant locks
3686a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
3696a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
3706a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
3716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
3726a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADATEND, SL_PLAYEVENT_HEADMOVING fit?
3736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
3741ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
3751ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
3761ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3771ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
3781ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
379a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivistatic void android_pushAudioTrackCallback(int event, void* user, void *info) {
380a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    if (event == android::AudioTrack::EVENT_MORE_DATA) {
381a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        fprintf(stderr, "received event EVENT_MORE_DATA from AudioTrack\n");
382a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        // set size to 0 to signal we're not using the callback to write more data
383a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
384a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        pBuff->size = 0;
385a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
386a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    } else if (event == android::AudioTrack::EVENT_MARKER) {
387a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        fprintf(stderr, "received event EVENT_MARKER from AudioTrack\n");
388a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    } else if (event == android::AudioTrack::EVENT_NEW_POS) {
389a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        fprintf(stderr, "received event EVENT_NEW_POS from AudioTrack\n");
390a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
391a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
392a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
393a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
394a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
3956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerCreate(const SLDataSource *pAudioSrc,
39672a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten        const SLDataSink *pAudioSnk,
39772a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten        CAudioPlayer *pAudioPlayer) {
398773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
399c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
400c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
401a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //--------------------------------------
402a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // Output check:
403c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // currently only OutputMix sinks are supported
404c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // this has been verified in sles_to_android_CheckAudioPlayerSourceSink
405c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
406c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //--------------------------------------
407c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    // Source check:
408c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
409c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    switch (locatorType) {
410a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
411a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   Buffer Queue to AudioTrack
412c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
4131ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL;
414c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
415a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //   -----------------------------------
4166fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI to MediaPlayer
4176fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI: {
418c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = MEDIAPLAYER;
4196fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        // save URI
4206fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
4216fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        pAudioPlayer->mUri = (char*) malloc(1 + sizeof(SLchar)*strlen((char*)dl_uri->URI));
4226fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        strcpy(pAudioPlayer->mUri, (char*)dl_uri->URI);
4236fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
424c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
425c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
426c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
427c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
428c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
429c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
430c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return result;
431773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
432773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
433773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
434a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
435a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
4366fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel TriviSLresult sles_to_android_audioPlayerRealize(CAudioPlayer *pAudioPlayer, SLboolean async) {
437a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
438a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
4396fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //fprintf(stderr, "entering sles_to_android_audioPlayerRealize\n");
440a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
441a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
442a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
4436a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
4441ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
445a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        {
446a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
447a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource;
448a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
449a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
450a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
451a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
452a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
453a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        pAudioPlayer->mAudioTrack = new android::AudioTrack(
454a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                ANDROID_DEFAULT_OUTPUT_STREAM_TYPE,                  // streamType
455a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
456a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
457a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask
4581ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0,                                                   // frameCount (here min)
459a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                0,                                                   // flags
4601ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                android_pullAudioTrackCallback,                      // callback
461a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
4621ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                0);  // FIXME find appropriate frame count         // notificationFrame
463a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
464a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        if (pAudioPlayer->mAudioTrack->initCheck() != android::NO_ERROR) {
4656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
466a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
467a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        break;
468a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
469a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
4706fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case MEDIAPLAYER: {
471a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        pAudioPlayer->mMediaPlayer = new android::MediaPlayer();
4726fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        if (pAudioPlayer->mMediaPlayer == NULL) {
4736fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            result = SL_RESULT_MEMORY_FAILURE;
4746fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            break;
4756fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
4766fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        pAudioPlayer->mMediaPlayer->setAudioStreamType(ANDROID_DEFAULT_OUTPUT_STREAM_TYPE);
4776fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        if (pAudioPlayer->mMediaPlayer->setDataSource(android::String8(pAudioPlayer->mUri), NULL)
4786fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                != android::NO_ERROR) {
4796fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
4806fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            break;
4816fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
4826fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi
4836fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        // FIXME move the call to MediaPlayer::prepare() to the start of the prefetching
4846fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        //       i.e. in SL ES: when setting the play state of the AudioPlayer to Paused.
4856fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        if (async == SL_BOOLEAN_FALSE) {
4866fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            if (pAudioPlayer->mMediaPlayer->prepare() != android::NO_ERROR) {
4876fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                fprintf(stderr, "Failed to prepare() MediaPlayer in synchronous mode for %s\n",
4886fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                        pAudioPlayer->mUri);
4896fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi                result = SL_RESULT_CONTENT_UNSUPPORTED;
4906fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            }
4916fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } else {
4926fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            // FIXME verify whether async prepare will be handled by SL ES framework or
4936fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            //       Android-specific code (and rely on MediaPlayer::prepareAsync() )
4946fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "FIXME implement async realize for a MediaPlayer\n");
4956fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
4966fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
497a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        break;
498a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
499a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
500a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
501a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
502a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
503a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
504a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
50548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
50648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
5076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerDestroy(CAudioPlayer *pAudioPlayer) {
5086a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
5096a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //fprintf(stdout, "sles_to_android_audioPlayerDestroy\n");
5106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
5116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
5126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // AudioTrack
5136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
5146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
5156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        pAudioPlayer->mAudioTrack->stop();
5166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        delete pAudioPlayer->mAudioTrack;
5176a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        pAudioPlayer->mAudioTrack = NULL;
5186a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
5196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
5206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    //-----------------------------------
5216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // MediaPlayer
5226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
5236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME destroy MediaPlayer
5246fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        if (pAudioPlayer->mMediaPlayer != NULL) {
5256fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            pAudioPlayer->mMediaPlayer->stop();
5266fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            pAudioPlayer->mMediaPlayer->setListener(0);
5276fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            pAudioPlayer->mMediaPlayer->disconnect();
5286fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stderr, "FIXME destroy MediaPlayer\n");
5296fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            //delete pAudioPlayer->mMediaPlayer;
5306fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            pAudioPlayer->mMediaPlayer = NULL;
5316fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            free(pAudioPlayer->mUri);
5326fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
5336a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
5346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
5356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = SL_RESULT_CONTENT_UNSUPPORTED;
5366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
5376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
5396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
5406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
54372a04d8e9e059dad969d166a6a70491fe1e65970Glenn KastenSLresult sles_to_android_audioPlayerSetPlayState(IPlay *pPlayItf, SLuint32 state) {
54472a04d8e9e059dad969d166a6a70491fe1e65970Glenn Kasten    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
54548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    switch(ap->mAndroidObjType) {
54648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case AUDIOTRACK_PUSH:
5471ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    case AUDIOTRACK_PULL:
54848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        switch (state) {
54948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
55048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
55148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            ap->mAudioTrack->stop();
55248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
55348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
55448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
55548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            ap->mAudioTrack->pause();
55648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
55748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
55848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
55948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            ap->mAudioTrack->start();
56048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
56148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
56248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
56348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
56448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
56548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    case MEDIAPLAYER:
5666fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        switch (state) {
5676fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
5686fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_STOPPED\n");
5696fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            ap->mMediaPlayer->stop();
5706fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            break;
5716fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
5726fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PAUSED\n");
5736fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            //FIXME implement start of prefetching when transitioning from stopped to paused
5746fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            ap->mMediaPlayer->pause();
5756fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            break;
5766fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
5776fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            fprintf(stdout, "setting AudioPlayer to SL_PLAYSTATE_PLAYING\n");
5786fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            ap->mMediaPlayer->start();
5796fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            break;
5806fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        default:
5816fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
5826fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        }
58348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
58448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
58548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
58648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
58748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    return SL_RESULT_SUCCESS;
58848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
58948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
5906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
5916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
5926a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerUseEventMask(IPlay *pPlayItf, SLuint32 eventFlags) {
5936a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
5946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
5956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
5966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
5976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
5986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            ap->mAudioTrack->setMarkerPosition( (uint32_t)((pPlayItf->mMarkerPosition
5996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    * ap->mAudioTrack->getSampleRate())/1000));
6006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        } else {
6016a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // clear marker
6026a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            ap->mAudioTrack->setMarkerPosition(0);
6036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
6046a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
6056a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            ap->mAudioTrack->setPositionUpdatePeriod( (uint32_t)((pPlayItf->mPositionUpdatePeriod
6066a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi                    * ap->mAudioTrack->getSampleRate())/1000));
6076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        } else {
6086a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // clear periodic update
6096a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            ap->mAudioTrack->setPositionUpdatePeriod(0);
6106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
6116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (eventFlags & SL_PLAYEVENT_HEADATEND) {
6126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME support SL_PLAYEVENT_HEADATEND
6136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            fprintf(stderr, "FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADATEND) on an SL_OBJECTID_AUDIOPLAYER to be implemented\n");
6146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
6156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
6166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME support SL_PLAYEVENT_HEADMOVING
6176a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            fprintf(stderr, "FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an SL_OBJECTID_AUDIOPLAYER to be implemented\n");
6186a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
6196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
6206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME support SL_PLAYEVENT_HEADSTALLED
6216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            fprintf(stderr, "FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADSTALLED) on an SL_OBJECTID_AUDIOPLAYER to be implemented\n");
6226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
6236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6246a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
6256a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //FIXME implement
6266a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        fprintf(stderr, "FIXME: IPlay_SetCallbackEventsMask() mapped to a MediaPlayer to be implemented\n");
6276a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6286a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
6296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
6316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
6326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6336a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
6346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6356a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6366a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
6376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerGetPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
6386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
6396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(ap->mAndroidObjType) {
6406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PUSH:
6416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case AUDIOTRACK_PULL:
6426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        uint32_t positionInFrames;
6436a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        ap->mAudioTrack->getPosition(&positionInFrames);
6446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        *pPosMsec = positionInFrames * 1000 / ap->mAudioTrack->getSampleRate();
6456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    case MEDIAPLAYER:
6476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        //FIXME implement
6486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        fprintf(stderr, "FIXME: sles_to_android_audioPlayerGetPosition() mapped to a MediaPlayer to be implemented\n");
6496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
6516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
6526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
6536a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
6546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
6556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6566a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
6576a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerVolumeUpdate(IVolume *pVolItf) {
6586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pVolItf->mThis;
6596a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME use the FX Framework conversions
6606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    android_audioPlayerUpdateStereoVolume(pVolItf);
6616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
6626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
6636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
6656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
6666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel TriviSLresult sles_to_android_audioPlayerSetMute(IVolume *pVolItf, SLboolean mute) {
6676a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pVolItf->mThis;
668b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    switch(ap->mAndroidObjType) {
669b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PUSH:
670b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case AUDIOTRACK_PULL:
671b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        // when unmuting: volume levels have already been updated in IVolume_SetMute
672b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        ap->mAudioTrack->mute(mute == SL_BOOLEAN_TRUE);
673b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
674b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    case MEDIAPLAYER:
675b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        if (mute == SL_BOOLEAN_TRUE) {
6766a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            ap->mMediaPlayer->setVolume(0.0f, 0.0f);
6776a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
678b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        // when unmuting: volume levels have already been updated in IVolume_SetMute which causes
679b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        // the MediaPlayer to receive non 0 amplification values
680b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
681b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    default:
682b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        break;
6836a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
6846a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return SL_RESULT_SUCCESS;
6856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
6866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
687b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi
688