AudioPlayer_to_android.cpp revision a9a70a4451545034c9263dd55b181f2912534c37
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "sles_allinclusive.h"
18#include "utils/RefBase.h"
19#include "android_prompts.h"
20
21template class android::KeyedVector<SLuint32, android::AudioEffect* > ;
22
23#define KEY_STREAM_TYPE_PARAMSIZE  sizeof(SLint32)
24
25//-----------------------------------------------------------------------------
26int android_getMinFrameCount(uint32_t sampleRate) {
27    int afSampleRate;
28    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
29            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
30        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
31    }
32    int afFrameCount;
33    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
34            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
35        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
36    }
37    uint32_t afLatency;
38    if (android::AudioSystem::getOutputLatency(&afLatency,
39            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
40        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
41    }
42    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
43    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
44    if (minBufCount < 2) minBufCount = 2;
45    // minimum number of frames to cover output latency at the sample rate of the content
46    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
47}
48
49
50//-----------------------------------------------------------------------------
51#define LEFT_CHANNEL_MASK  0x1 << 0
52#define RIGHT_CHANNEL_MASK 0x1 << 1
53
54static void android_audioPlayer_updateStereoVolume(CAudioPlayer* ap) {
55    float leftVol = 1.0f, rightVol = 1.0f;
56
57    if (NULL == ap->mAudioTrack) {
58        return;
59    }
60    // should not be used when muted
61    if (SL_BOOLEAN_TRUE == ap->mMute) {
62        return;
63    }
64
65    int channelCount = ap->mNumChannels;
66
67    // mute has priority over solo
68    int leftAudibilityFactor = 1, rightAudibilityFactor = 1;
69
70    if (channelCount >= STEREO_CHANNELS) {
71        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
72            // left muted
73            leftAudibilityFactor = 0;
74        } else {
75            // left not muted
76            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
77                // left soloed
78                leftAudibilityFactor = 1;
79            } else {
80                // left not soloed
81                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
82                    // right solo silences left
83                    leftAudibilityFactor = 0;
84                } else {
85                    // left and right are not soloed, and left is not muted
86                    leftAudibilityFactor = 1;
87                }
88            }
89        }
90
91        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
92            // right muted
93            rightAudibilityFactor = 0;
94        } else {
95            // right not muted
96            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
97                // right soloed
98                rightAudibilityFactor = 1;
99            } else {
100                // right not soloed
101                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
102                    // left solo silences right
103                    rightAudibilityFactor = 0;
104                } else {
105                    // left and right are not soloed, and right is not muted
106                    rightAudibilityFactor = 1;
107                }
108            }
109        }
110    }
111
112    // compute amplification as the combination of volume level and stereo position
113    //   amplification from volume level
114    ap->mAmplFromVolLevel = sles_to_android_amplification(ap->mVolume.mLevel);
115    //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
116    leftVol  *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel;
117    rightVol *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel;
118
119    // amplification from stereo position
120    if (ap->mVolume.mEnableStereoPosition) {
121        // panning law depends on number of channels of content: stereo panning vs 2ch. balance
122        if(1 == channelCount) {
123            // stereo panning
124            double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
125            ap->mAmplFromStereoPos[0] = cos(theta);
126            ap->mAmplFromStereoPos[1] = sin(theta);
127        } else {
128            // stereo balance
129            if (ap->mVolume.mStereoPosition > 0) {
130                ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f;
131                ap->mAmplFromStereoPos[1] = 1.0f;
132            } else {
133                ap->mAmplFromStereoPos[0] = 1.0f;
134                ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f;
135            }
136        }
137        leftVol  *= ap->mAmplFromStereoPos[0];
138        rightVol *= ap->mAmplFromStereoPos[1];
139    }
140
141    ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor);
142
143    // changes in the AudioPlayer volume must be reflected in the send level:
144    //  in SLEffectSendItf or in SLAndroidEffectSendItf?
145    // FIXME replace interface test by an internal API once we have one.
146    if (NULL != ap->mEffectSend.mItf) {
147        for (unsigned int i=0 ; i<AUX_MAX ; i++) {
148            if (ap->mEffectSend.mEnableLevels[i].mEnable) {
149                android_fxSend_setSendLevel(ap,
150                        ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
151                // there's a single aux bus on Android, so we can stop looking once the first
152                // aux effect is found.
153                break;
154            }
155        }
156    } else if (NULL != ap->mAndroidEffectSend.mItf) {
157        android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
158    }
159}
160
161//-----------------------------------------------------------------------------
162void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
163    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
164    slPlayCallback callback = NULL;
165    void* callbackPContext = NULL;
166
167    interface_lock_shared(&ap->mPlay);
168    callback = ap->mPlay.mCallback;
169    callbackPContext = ap->mPlay.mContext;
170    interface_unlock_shared(&ap->mPlay);
171
172    if (NULL != callback) {
173        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
174        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
175    }
176}
177
178//-----------------------------------------------------------------------------
179void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
180    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
181    slPlayCallback callback = NULL;
182    void* callbackPContext = NULL;
183
184    interface_lock_shared(&ap->mPlay);
185    callback = ap->mPlay.mCallback;
186    callbackPContext = ap->mPlay.mContext;
187    interface_unlock_shared(&ap->mPlay);
188
189    if (NULL != callback) {
190        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
191        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
192    }
193}
194
195
196//-----------------------------------------------------------------------------
197void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
198    slPlayCallback callback = NULL;
199    void* callbackPContext = NULL;
200
201    interface_lock_shared(&ap->mPlay);
202    callback = ap->mPlay.mCallback;
203    callbackPContext = ap->mPlay.mContext;
204    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
205    interface_unlock_shared(&ap->mPlay);
206
207    if ((NULL != callback) && headStalled) {
208        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
209    }
210}
211
212
213//-----------------------------------------------------------------------------
214/**
215 * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
216 *
217 * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
218 *       needs to be changed when the player reaches the end of the content to play. This is
219 *       relative to what the specification describes for buffer queues vs the
220 *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
221 *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
222 *          buffers in the queue, the playing of audio data stops. The player remains in the
223 *          SL_PLAYSTATE_PLAYING state."
224 *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
225 *          of the current content and the player has paused."
226 */
227void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
228        bool needToLock) {
229    //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
230    //        needToLock);
231    slPlayCallback playCallback = NULL;
232    void * playContext = NULL;
233    // SLPlayItf callback or no callback?
234    if (needToLock) {
235        interface_lock_exclusive(&ap->mPlay);
236    }
237    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
238        playCallback = ap->mPlay.mCallback;
239        playContext = ap->mPlay.mContext;
240    }
241    if (setPlayStateToPaused) {
242        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
243    }
244    if (needToLock) {
245        interface_unlock_exclusive(&ap->mPlay);
246    }
247    // callback with no lock held
248    if (NULL != playCallback) {
249        (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
250    }
251
252}
253
254
255//-----------------------------------------------------------------------------
256/**
257 * pre-condition: AudioPlayer has SLPrefetchStatusItf initialized
258 * post-condition:
259 *  - ap->mPrefetchStatus.mStatus == status
260 *  - the prefetch status callback, if any, has been notified if a change occurred
261 *
262 */
263void audioPlayer_dispatch_prefetchStatus_lockPrefetch(CAudioPlayer *ap, SLuint32 status,
264        bool needToLock) {
265    slPrefetchCallback prefetchCallback = NULL;
266    void * prefetchContext = NULL;
267
268    if (needToLock) {
269        interface_lock_exclusive(&ap->mPrefetchStatus);
270    }
271    // status change?
272    if (ap->mPrefetchStatus.mStatus != status) {
273        ap->mPrefetchStatus.mStatus = status;
274        // callback or no callback?
275        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
276            prefetchCallback = ap->mPrefetchStatus.mCallback;
277            prefetchContext  = ap->mPrefetchStatus.mContext;
278        }
279    }
280    if (needToLock) {
281        interface_unlock_exclusive(&ap->mPrefetchStatus);
282    }
283
284    // callback with no lock held
285    if (NULL != prefetchCallback) {
286        (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, status);
287    }
288}
289
290
291//-----------------------------------------------------------------------------
292SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
293    SLresult result = SL_RESULT_SUCCESS;
294    SL_LOGV("type %ld", type);
295
296    int newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
297    switch(type) {
298    case SL_ANDROID_STREAM_VOICE:
299        newStreamType = android::AudioSystem::VOICE_CALL;
300        break;
301    case SL_ANDROID_STREAM_SYSTEM:
302        newStreamType = android::AudioSystem::SYSTEM;
303        break;
304    case SL_ANDROID_STREAM_RING:
305        newStreamType = android::AudioSystem::RING;
306        break;
307    case SL_ANDROID_STREAM_MEDIA:
308        newStreamType = android::AudioSystem::MUSIC;
309        break;
310    case SL_ANDROID_STREAM_ALARM:
311        newStreamType = android::AudioSystem::ALARM;
312        break;
313    case SL_ANDROID_STREAM_NOTIFICATION:
314        newStreamType = android::AudioSystem::NOTIFICATION;
315        break;
316    default:
317        SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
318        result = SL_RESULT_PARAMETER_INVALID;
319        break;
320    }
321
322    // stream type needs to be set before the object is realized
323    // (ap->mAudioTrack is supposed to be NULL until then)
324    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
325        SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
326        result = SL_RESULT_PRECONDITIONS_VIOLATED;
327    } else {
328        ap->mStreamType = newStreamType;
329    }
330
331    return result;
332}
333
334
335//-----------------------------------------------------------------------------
336SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
337    SLresult result = SL_RESULT_SUCCESS;
338
339    switch(ap->mStreamType) {
340    case android::AudioSystem::VOICE_CALL:
341        *pType = SL_ANDROID_STREAM_VOICE;
342        break;
343    case android::AudioSystem::SYSTEM:
344        *pType = SL_ANDROID_STREAM_SYSTEM;
345        break;
346    case android::AudioSystem::RING:
347        *pType = SL_ANDROID_STREAM_RING;
348        break;
349    case android::AudioSystem::DEFAULT:
350    case android::AudioSystem::MUSIC:
351        *pType = SL_ANDROID_STREAM_MEDIA;
352        break;
353    case android::AudioSystem::ALARM:
354        *pType = SL_ANDROID_STREAM_ALARM;
355        break;
356    case android::AudioSystem::NOTIFICATION:
357        *pType = SL_ANDROID_STREAM_NOTIFICATION;
358        break;
359    default:
360        result = SL_RESULT_INTERNAL_ERROR;
361        *pType = SL_ANDROID_STREAM_MEDIA;
362        break;
363    }
364
365    return result;
366}
367
368
369//-----------------------------------------------------------------------------
370#ifndef USE_BACKPORT
371static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) {
372
373    if (lockAP) { object_lock_exclusive(&ap->mObject); }
374    ap->mAndroidObjState = ANDROID_PREPARING;
375    if (lockAP) { object_unlock_exclusive(&ap->mObject); }
376
377    if (ap->mSfPlayer != 0) {
378        ap->mSfPlayer->prepare();
379    }
380}
381#endif
382
383//-----------------------------------------------------------------------------
384#ifndef USE_BACKPORT
385// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
386// from a URI or FD, for prepare and prefetch events
387static void sfplayer_handlePrefetchEvent(const int event, const int data1, void* user) {
388    if (NULL == user) {
389        return;
390    }
391
392    CAudioPlayer *ap = (CAudioPlayer *)user;
393    //SL_LOGV("received event %d, data %d from SfAudioPlayer", event, data1);
394    switch(event) {
395
396    case(android::SfPlayer::kEventPrepared): {
397        object_lock_exclusive(&ap->mObject);
398
399        if (SFPLAYER_SUCCESS != data1) {
400            ap->mAudioTrack = NULL;
401            ap->mNumChannels = 0;
402            ap->mSampleRateMilliHz = 0;
403            ap->mAndroidObjState = ANDROID_UNINITIALIZED;
404
405        } else {
406            ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
407            ap->mNumChannels = ap->mSfPlayer->getNumChannels();
408            ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
409            ap->mSfPlayer->startPrefetch_async();
410
411            // update the new track with the current settings
412            android_audioPlayer_useEventMask(ap);
413            android_audioPlayer_volumeUpdate(ap);
414            android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/);
415
416            ap->mAndroidObjState = ANDROID_READY;
417        }
418
419        object_unlock_exclusive(&ap->mObject);
420    } break;
421
422    case(android::SfPlayer::kEventPrefetchFillLevelUpdate): {
423        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
424            break;
425        }
426        slPrefetchCallback callback = NULL;
427        void* callbackPContext = NULL;
428
429        // SLPrefetchStatusItf callback or no callback?
430        interface_lock_exclusive(&ap->mPrefetchStatus);
431        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
432            callback = ap->mPrefetchStatus.mCallback;
433            callbackPContext = ap->mPrefetchStatus.mContext;
434        }
435        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
436        interface_unlock_exclusive(&ap->mPrefetchStatus);
437
438        // callback with no lock held
439        if (NULL != callback) {
440            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
441                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
442        }
443    } break;
444
445    case(android::SfPlayer::kEventPrefetchStatusChange): {
446        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
447            break;
448        }
449        slPrefetchCallback callback = NULL;
450        void* callbackPContext = NULL;
451
452        // SLPrefetchStatusItf callback or no callback?
453        object_lock_exclusive(&ap->mObject);
454        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
455            callback = ap->mPrefetchStatus.mCallback;
456            callbackPContext = ap->mPrefetchStatus.mContext;
457        }
458        if (data1 >= android::SfPlayer::kStatusIntermediate) {
459            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
460            // FIXME estimate fill level better?
461            ap->mPrefetchStatus.mLevel = 1000;
462            ap->mAndroidObjState = ANDROID_READY;
463        } else if (data1 < android::SfPlayer::kStatusIntermediate) {
464            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
465            // FIXME estimate fill level better?
466            ap->mPrefetchStatus.mLevel = 0;
467        }
468        object_unlock_exclusive(&ap->mObject);
469
470        // callback with no lock held
471        if (NULL != callback) {
472            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
473        }
474        } break;
475
476    case(android::SfPlayer::kEventEndOfStream): {
477        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
478        if ((NULL != ap->mAudioTrack) && (!ap->mSeek.mLoopEnabled)) {
479            ap->mAudioTrack->stop();
480        }
481        } break;
482
483    default:
484        break;
485    }
486}
487#endif
488
489
490//-----------------------------------------------------------------------------
491SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
492{
493    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
494    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
495    //--------------------------------------
496    // Sink check:
497    //     currently only OutputMix sinks are supported, regardless of the data source
498    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
499        SL_LOGE("Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX");
500        return SL_RESULT_PARAMETER_INVALID;
501    }
502
503    //--------------------------------------
504    // Source check:
505    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
506    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
507
508    switch (locatorType) {
509    //------------------
510    //   Buffer Queues
511    case SL_DATALOCATOR_BUFFERQUEUE:
512    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
513        {
514        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
515
516        // Buffer format
517        switch (formatType) {
518        //     currently only PCM buffer queues are supported,
519        case SL_DATAFORMAT_PCM: {
520            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
521            switch (df_pcm->numChannels) {
522            case 1:
523            case 2:
524                break;
525            default:
526                // this should have already been rejected by checkDataFormat
527                SL_LOGE("Cannot create audio player: unsupported " \
528                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
529                return SL_RESULT_CONTENT_UNSUPPORTED;
530            }
531            switch (df_pcm->samplesPerSec) {
532            case SL_SAMPLINGRATE_8:
533            case SL_SAMPLINGRATE_11_025:
534            case SL_SAMPLINGRATE_12:
535            case SL_SAMPLINGRATE_16:
536            case SL_SAMPLINGRATE_22_05:
537            case SL_SAMPLINGRATE_24:
538            case SL_SAMPLINGRATE_32:
539            case SL_SAMPLINGRATE_44_1:
540                break;
541            case SL_SAMPLINGRATE_48:    // not 48?
542            case SL_SAMPLINGRATE_64:
543            case SL_SAMPLINGRATE_88_2:
544            case SL_SAMPLINGRATE_96:
545            case SL_SAMPLINGRATE_192:
546            default:
547                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
548                    (unsigned) df_pcm->samplesPerSec);
549                return SL_RESULT_CONTENT_UNSUPPORTED;
550            }
551            switch (df_pcm->bitsPerSample) {
552            case SL_PCMSAMPLEFORMAT_FIXED_8:
553                // FIXME We should support this
554                SL_LOGE("Cannot create audio player: unsupported 8-bit data");
555                return SL_RESULT_CONTENT_UNSUPPORTED;
556            case SL_PCMSAMPLEFORMAT_FIXED_16:
557                break;
558                // others
559            default:
560                // this should have already been rejected by checkDataFormat
561                SL_LOGE("Cannot create audio player: unsupported sample bit depth %lu",
562                        (SLuint32)df_pcm->bitsPerSample);
563                return SL_RESULT_CONTENT_UNSUPPORTED;
564            }
565            switch (df_pcm->containerSize) {
566            case 16:
567                break;
568                // others
569            default:
570                SL_LOGE("Cannot create audio player: unsupported container size %u",
571                    (unsigned) df_pcm->containerSize);
572                return SL_RESULT_CONTENT_UNSUPPORTED;
573            }
574            switch (df_pcm->channelMask) {
575                // FIXME needs work
576            default:
577                break;
578            }
579            switch (df_pcm->endianness) {
580            case SL_BYTEORDER_LITTLEENDIAN:
581                break;
582            case SL_BYTEORDER_BIGENDIAN:
583                SL_LOGE("Cannot create audio player: unsupported big-endian byte order");
584                return SL_RESULT_CONTENT_UNSUPPORTED;
585                // native is proposed but not yet in spec
586            default:
587                SL_LOGE("Cannot create audio player: unsupported byte order %u",
588                    (unsigned) df_pcm->endianness);
589                return SL_RESULT_CONTENT_UNSUPPORTED;
590            }
591            } //case SL_DATAFORMAT_PCM
592            break;
593        case SL_DATAFORMAT_MIME:
594        case SL_DATAFORMAT_RESERVED3:
595            SL_LOGE("Cannot create audio player with buffer queue data source "
596                "without SL_DATAFORMAT_PCM format");
597            return SL_RESULT_CONTENT_UNSUPPORTED;
598        default:
599            SL_LOGE("Cannot create audio player with buffer queue data source "
600                "without SL_DATAFORMAT_PCM format");
601            return SL_RESULT_PARAMETER_INVALID;
602        } // switch (formatType)
603        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
604        break;
605    //------------------
606    //   URI
607    case SL_DATALOCATOR_URI:
608        {
609        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
610        if (NULL == dl_uri->URI) {
611            return SL_RESULT_PARAMETER_INVALID;
612        }
613        // URI format
614        switch (formatType) {
615        case SL_DATAFORMAT_MIME:
616            break;
617        case SL_DATAFORMAT_PCM:
618        case SL_DATAFORMAT_RESERVED3:
619            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
620                "SL_DATAFORMAT_MIME format");
621            return SL_RESULT_CONTENT_UNSUPPORTED;
622        } // switch (formatType)
623        } // case SL_DATALOCATOR_URI
624        break;
625    //------------------
626    //   File Descriptor
627    case SL_DATALOCATOR_ANDROIDFD:
628        {
629        // fd is already non null
630        switch (formatType) {
631        case SL_DATAFORMAT_MIME:
632            break;
633        case SL_DATAFORMAT_PCM:
634            // FIXME implement
635            SL_LOGD("[ FIXME implement PCM FD data sources ]");
636            break;
637        case SL_DATAFORMAT_RESERVED3:
638            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
639                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
640            return SL_RESULT_CONTENT_UNSUPPORTED;
641        } // switch (formatType)
642        } // case SL_DATALOCATOR_ANDROIDFD
643        break;
644    //------------------
645    //   Address
646    case SL_DATALOCATOR_ADDRESS:
647    case SL_DATALOCATOR_IODEVICE:
648    case SL_DATALOCATOR_OUTPUTMIX:
649    case SL_DATALOCATOR_RESERVED5:
650    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
651    case SL_DATALOCATOR_RESERVED8:
652        SL_LOGE("Cannot create audio player with data locator type 0x%x", (unsigned) locatorType);
653        return SL_RESULT_CONTENT_UNSUPPORTED;
654    default:
655        return SL_RESULT_PARAMETER_INVALID;
656    }// switch (locatorType)
657
658    return SL_RESULT_SUCCESS;
659}
660
661
662
663//-----------------------------------------------------------------------------
664static void audioTrack_callBack_uri(int event, void* user, void *info) {
665    // EVENT_MORE_DATA needs to be handled with priority over the other events
666    // because it will be called the most often during playback
667    if (event == android::AudioTrack::EVENT_MORE_DATA) {
668        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
669        // set size to 0 to signal we're not using the callback to write more data
670        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
671        pBuff->size = 0;
672    } else if (NULL != user) {
673        switch (event) {
674            case (android::AudioTrack::EVENT_MARKER) :
675                audioTrack_handleMarker_lockPlay((CAudioPlayer *)user);
676                break;
677            case (android::AudioTrack::EVENT_NEW_POS) :
678                audioTrack_handleNewPos_lockPlay((CAudioPlayer *)user);
679                break;
680            case (android::AudioTrack::EVENT_UNDERRUN) :
681                audioTrack_handleUnderrun_lockPlay((CAudioPlayer *)user);
682                break;
683            default:
684                SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
685                        (CAudioPlayer *)user);
686                break;
687        }
688    }
689}
690
691//-----------------------------------------------------------------------------
692// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
693// from a buffer queue.
694static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
695    CAudioPlayer *ap = (CAudioPlayer *)user;
696    void * callbackPContext = NULL;
697    switch(event) {
698
699    case (android::AudioTrack::EVENT_MORE_DATA) : {
700        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
701        slBufferQueueCallback callback = NULL;
702        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
703        // retrieve data from the buffer queue
704        interface_lock_exclusive(&ap->mBufferQueue);
705        if (ap->mBufferQueue.mState.count != 0) {
706            //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count);
707            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
708
709            BufferHeader *oldFront = ap->mBufferQueue.mFront;
710            BufferHeader *newFront = &oldFront[1];
711
712            // FIXME handle 8bit based on buffer format
713            short *pSrc = (short*)((char *)oldFront->mBuffer
714                    + ap->mBufferQueue.mSizeConsumed);
715            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
716                // can't consume the whole or rest of the buffer in one shot
717                ap->mBufferQueue.mSizeConsumed += pBuff->size;
718                // leave pBuff->size untouched
719                // consume data
720                // FIXME can we avoid holding the lock during the copy?
721                memcpy (pBuff->i16, pSrc, pBuff->size);
722            } else {
723                // finish consuming the buffer or consume the buffer in one shot
724                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
725                ap->mBufferQueue.mSizeConsumed = 0;
726
727                if (newFront ==
728                        &ap->mBufferQueue.mArray
729                            [ap->mBufferQueue.mNumBuffers + 1])
730                {
731                    newFront = ap->mBufferQueue.mArray;
732                }
733                ap->mBufferQueue.mFront = newFront;
734
735                ap->mBufferQueue.mState.count--;
736                ap->mBufferQueue.mState.playIndex++;
737
738                // consume data
739                // FIXME can we avoid holding the lock during the copy?
740                memcpy (pBuff->i16, pSrc, pBuff->size);
741
742                // data has been consumed, and the buffer queue state has been updated
743                // we will notify the client if applicable
744                callback = ap->mBufferQueue.mCallback;
745                // save callback data
746                callbackPContext = ap->mBufferQueue.mContext;
747            }
748        } else { // empty queue
749            // signal no data available
750            pBuff->size = 0;
751
752            // signal we're at the end of the content, but don't pause (see note in function)
753            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
754
755            // signal underflow to prefetch status itf
756            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
757                audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_UNDERFLOW,
758                    false);
759            }
760
761            // stop the track so it restarts playing faster when new data is enqueued
762            ap->mAudioTrack->stop();
763        }
764        interface_unlock_exclusive(&ap->mBufferQueue);
765        // notify client
766        if (NULL != callback) {
767            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
768        }
769    }
770    break;
771
772    case (android::AudioTrack::EVENT_MARKER) :
773        audioTrack_handleMarker_lockPlay(ap);
774        break;
775
776    case (android::AudioTrack::EVENT_NEW_POS) :
777        audioTrack_handleNewPos_lockPlay(ap);
778        break;
779
780    case (android::AudioTrack::EVENT_UNDERRUN) :
781        audioTrack_handleUnderrun_lockPlay(ap);
782        break;
783
784    default:
785        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
786        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
787                (CAudioPlayer *)user);
788        break;
789    }
790}
791
792
793//-----------------------------------------------------------------------------
794SLresult android_audioPlayer_create(
795        CAudioPlayer *pAudioPlayer) {
796
797    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
798    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
799    SLresult result = SL_RESULT_SUCCESS;
800
801    //--------------------------------------
802    // Sink check:
803    // currently only OutputMix sinks are supported
804    // this has already been verified in sles_to_android_CheckAudioPlayerSourceSink
805    // SLuint32 locatorType = *(SLuint32 *)pAudioSnk->pLocator;
806    // if (SL_DATALOCATOR_OUTPUTMIX == locatorType) {
807    // }
808
809    //--------------------------------------
810    // Source check:
811    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
812    switch (locatorType) {
813    //   -----------------------------------
814    //   Buffer Queue to AudioTrack
815    case SL_DATALOCATOR_BUFFERQUEUE:
816    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
817        pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL;
818        pAudioPlayer->mpLock = new android::Mutex();
819        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
820        break;
821    //   -----------------------------------
822    //   URI or FD to MediaPlayer
823    case SL_DATALOCATOR_URI:
824    case SL_DATALOCATOR_ANDROIDFD:
825        pAudioPlayer->mAndroidObjType = MEDIAPLAYER;
826        pAudioPlayer->mpLock = new android::Mutex();
827        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
828        break;
829    default:
830        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
831        pAudioPlayer->mpLock = NULL;
832        pAudioPlayer->mPlaybackRate.mCapabilities = 0;
833        result = SL_RESULT_PARAMETER_INVALID;
834        break;
835    }
836
837    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
838    pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
839    pAudioPlayer->mAudioTrack = NULL;
840#ifndef USE_BACKPORT
841    // no longer needed, as placement new (explicit constructor) already does this
842    // pAudioPlayer->mSfPlayer.clear();
843#endif
844
845#ifndef USE_BACKPORT
846    pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
847#endif
848
849    pAudioPlayer->mAmplFromVolLevel = 1.0f;
850    pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
851    pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
852    pAudioPlayer->mDirectLevel = 0; // no attenuation
853    pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
854
855    // initialize interface-specific fields that can be used regardless of whether the interface
856    // is exposed on the AudioPlayer or not
857    // (section no longer applicable, as all previous initializations were the same as the defaults)
858
859    return result;
860
861}
862
863
864//-----------------------------------------------------------------------------
865SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
866        const void *pConfigValue, SLuint32 valueSize) {
867
868    SLresult result = SL_RESULT_SUCCESS;
869
870    if (NULL == ap) {
871        result = SL_RESULT_INTERNAL_ERROR;
872    } else if (NULL == pConfigValue) {
873        SL_LOGE(ERROR_CONFIG_NULL_PARAM);
874        result = SL_RESULT_PARAMETER_INVALID;
875
876    } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
877
878        // stream type
879        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
880            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
881            result = SL_RESULT_PARAMETER_INVALID;
882        } else {
883            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
884        }
885
886    } else {
887        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
888        result = SL_RESULT_PARAMETER_INVALID;
889    }
890
891    return result;
892}
893
894
895//-----------------------------------------------------------------------------
896SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
897        SLuint32* pValueSize, void *pConfigValue) {
898
899    SLresult result = SL_RESULT_SUCCESS;
900
901    if (NULL == ap) {
902        return SL_RESULT_INTERNAL_ERROR;
903    } else if (NULL == pValueSize) {
904        SL_LOGE(ERROR_CONFIG_NULL_PARAM);
905        result = SL_RESULT_PARAMETER_INVALID;
906
907    } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
908
909        // stream type
910        if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
911            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
912            result = SL_RESULT_PARAMETER_INVALID;
913        } else {
914            *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
915            if (NULL != pConfigValue) {
916                result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
917            }
918        }
919
920    } else {
921        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
922        result = SL_RESULT_PARAMETER_INVALID;
923    }
924
925    return result;
926}
927
928
929//-----------------------------------------------------------------------------
930SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
931
932    SLresult result = SL_RESULT_SUCCESS;
933    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
934
935    switch (pAudioPlayer->mAndroidObjType) {
936    //-----------------------------------
937    // AudioTrack
938    case AUDIOTRACK_PULL:
939        {
940        // initialize platform-specific CAudioPlayer fields
941
942        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
943                pAudioPlayer->mDynamicSource.mDataSource;
944        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
945                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
946
947        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
948
949        pAudioPlayer->mAudioTrack = new android::AudioTrack(
950                pAudioPlayer->mStreamType,                           // streamType
951                sampleRate,                                          // sampleRate
952                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
953                sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask
954                0,                                                   // frameCount (here min)
955                0,                                                   // flags
956                audioTrack_callBack_pullFromBuffQueue,               // callback
957                (void *) pAudioPlayer,                               // user
958                0      // FIXME find appropriate frame count         // notificationFrame
959#ifndef USE_BACKPORT
960                , pAudioPlayer->mSessionId
961#endif
962                );
963        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
964        if (status != android::NO_ERROR) {
965            SL_LOGE("AudioTrack::initCheck status %u", status);
966            result = SL_RESULT_CONTENT_UNSUPPORTED;
967        }
968
969        // initialize platform-independent CAudioPlayer fields
970
971        pAudioPlayer->mNumChannels = df_pcm->numChannels;
972        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
973
974        pAudioPlayer->mAndroidObjState = ANDROID_READY;
975        } break;
976#ifndef USE_BACKPORT
977    //-----------------------------------
978    // MediaPlayer
979    case MEDIAPLAYER: {
980        object_lock_exclusive(&pAudioPlayer->mObject);
981
982        pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
983        pAudioPlayer->mNumChannels = 0;
984        pAudioPlayer->mSampleRateMilliHz = 0;
985        pAudioPlayer->mAudioTrack = NULL;
986
987        AudioPlayback_Parameters app;
988        app.sessionId = pAudioPlayer->mSessionId;
989        app.streamType = pAudioPlayer->mStreamType;
990        app.trackcb = audioTrack_callBack_uri;
991        app.trackcbUser = (void *) pAudioPlayer;
992
993        pAudioPlayer->mSfPlayer = new android::SfPlayer(&app);
994        pAudioPlayer->mSfPlayer->setNotifListener(sfplayer_handlePrefetchEvent,
995                        (void*)pAudioPlayer /*notifUSer*/);
996        pAudioPlayer->mSfPlayer->armLooper();
997
998        object_unlock_exclusive(&pAudioPlayer->mObject);
999
1000        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1001            case SL_DATALOCATOR_URI:
1002                pAudioPlayer->mSfPlayer->setDataSource(
1003                        (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1004                break;
1005            case SL_DATALOCATOR_ANDROIDFD: {
1006                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1007                pAudioPlayer->mSfPlayer->setDataSource(
1008                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1009                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1010                                (int64_t)SFPLAYER_FD_FIND_FILE_SIZE : offset,
1011                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1012                } break;
1013            default:
1014                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1015                break;
1016        }
1017
1018        } break;
1019#endif
1020    default:
1021        SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType);
1022        result = SL_RESULT_INTERNAL_ERROR;
1023        break;
1024    }
1025
1026#ifndef USE_BACKPORT
1027
1028    // proceed with effect initialization
1029    // initialize EQ
1030    // FIXME use a table of effect descriptors when adding support for more effects
1031    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1032            sizeof(effect_uuid_t)) == 0) {
1033        SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1034        android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1035    }
1036    // initialize BassBoost
1037    if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1038            sizeof(effect_uuid_t)) == 0) {
1039        SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1040        android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1041    }
1042    // initialize Virtualizer
1043    if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1044               sizeof(effect_uuid_t)) == 0) {
1045        SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1046        android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1047    }
1048
1049    // initialize EffectSend
1050    // FIXME initialize EffectSend
1051#endif
1052
1053    return result;
1054}
1055
1056
1057//-----------------------------------------------------------------------------
1058SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1059    SLresult result = SL_RESULT_SUCCESS;
1060    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1061    switch (pAudioPlayer->mAndroidObjType) {
1062    //-----------------------------------
1063    // AudioTrack
1064    case AUDIOTRACK_PULL:
1065        break;
1066#ifndef USE_BACKPORT
1067    //-----------------------------------
1068    // MediaPlayer
1069    case MEDIAPLAYER:
1070        // FIXME might no longer be needed since we call explicit destructor
1071        if (pAudioPlayer->mSfPlayer != 0) {
1072            pAudioPlayer->mSfPlayer.clear();
1073        }
1074        break;
1075#endif
1076    default:
1077        SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType);
1078        result = SL_RESULT_INTERNAL_ERROR;
1079        break;
1080    }
1081
1082    if (pAudioPlayer->mAudioTrack != NULL) {
1083        pAudioPlayer->mAudioTrack->stop();
1084        delete pAudioPlayer->mAudioTrack;
1085        pAudioPlayer->mAudioTrack = NULL;
1086    }
1087
1088    // FIXME might not be needed
1089    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
1090
1091    // explicit destructor
1092    pAudioPlayer->mSfPlayer.~sp();
1093
1094    if (pAudioPlayer->mpLock != NULL) {
1095        delete pAudioPlayer->mpLock;
1096        pAudioPlayer->mpLock = NULL;
1097    }
1098
1099    return result;
1100}
1101
1102
1103//-----------------------------------------------------------------------------
1104SLresult android_audioPlayer_setPlayRate(CAudioPlayer *ap, SLpermille rate, bool lockAP) {
1105    SLresult result = SL_RESULT_SUCCESS;
1106    uint32_t contentRate = 0;
1107    switch(ap->mAndroidObjType) {
1108    case AUDIOTRACK_PULL:
1109    case MEDIAPLAYER: {
1110        // get the content sample rate
1111        if (lockAP) { object_lock_shared(&ap->mObject); }
1112        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1113        if (lockAP) { object_unlock_shared(&ap->mObject); }
1114        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
1115        if (ap->mAudioTrack != NULL) {
1116            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
1117        }
1118        }
1119        break;
1120
1121    default:
1122        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1123        result = SL_RESULT_INTERNAL_ERROR;
1124        break;
1125    }
1126    return result;
1127}
1128
1129
1130//-----------------------------------------------------------------------------
1131// called with no lock held
1132SLresult android_audioPlayer_setPlaybackRateBehavior(CAudioPlayer *ap,
1133        SLuint32 constraints) {
1134    SLresult result = SL_RESULT_SUCCESS;
1135    switch(ap->mAndroidObjType) {
1136    case AUDIOTRACK_PULL:
1137    case MEDIAPLAYER:
1138        if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
1139            result = SL_RESULT_FEATURE_UNSUPPORTED;
1140        }
1141        break;
1142    default:
1143        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1144        result = SL_RESULT_INTERNAL_ERROR;
1145        break;
1146    }
1147    return result;
1148}
1149
1150
1151//-----------------------------------------------------------------------------
1152// called with no lock held
1153SLresult android_audioPlayer_getCapabilitiesOfRate(CAudioPlayer *ap,
1154        SLuint32 *pCapabilities) {
1155    switch(ap->mAndroidObjType) {
1156    case AUDIOTRACK_PULL:
1157    case MEDIAPLAYER:
1158        *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
1159        break;
1160    default:
1161        *pCapabilities = 0;
1162        break;
1163    }
1164    return SL_RESULT_SUCCESS;
1165}
1166
1167
1168//-----------------------------------------------------------------------------
1169void android_audioPlayer_setPlayState(CAudioPlayer *ap, bool lockAP) {
1170
1171    if (lockAP) { object_lock_shared(&ap->mObject); }
1172    SLuint32 playState = ap->mPlay.mState;
1173    AndroidObject_state objState = ap->mAndroidObjState;
1174    if (lockAP) { object_unlock_shared(&ap->mObject); }
1175
1176    switch(ap->mAndroidObjType) {
1177    case AUDIOTRACK_PULL:
1178        switch (playState) {
1179        case SL_PLAYSTATE_STOPPED:
1180            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1181            if (NULL != ap->mAudioTrack) {
1182                ap->mAudioTrack->stop();
1183            }
1184            break;
1185        case SL_PLAYSTATE_PAUSED:
1186            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1187            if (NULL != ap->mAudioTrack) {
1188                ap->mAudioTrack->pause();
1189            }
1190            break;
1191        case SL_PLAYSTATE_PLAYING:
1192            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1193            if (NULL != ap->mAudioTrack) {
1194                ap->mAudioTrack->start();
1195            }
1196            break;
1197        default:
1198            // checked by caller, should not happen
1199            break;
1200        }
1201        break;
1202#ifndef USE_BACKPORT
1203    case MEDIAPLAYER:
1204        switch (playState) {
1205        case SL_PLAYSTATE_STOPPED: {
1206            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1207            if (ap->mSfPlayer != 0) {
1208                ap->mSfPlayer->stop();
1209            }
1210            } break;
1211        case SL_PLAYSTATE_PAUSED: {
1212            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1213            switch(objState) {
1214                case(ANDROID_UNINITIALIZED):
1215                    sfplayer_prepare(ap, lockAP);
1216                    break;
1217                case(ANDROID_PREPARING):
1218                    break;
1219                case(ANDROID_READY):
1220                    if (ap->mSfPlayer != 0) {
1221                        ap->mSfPlayer->pause();
1222                    }
1223                    break;
1224                default:
1225                    break;
1226            }
1227            } break;
1228        case SL_PLAYSTATE_PLAYING: {
1229            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1230            switch(objState) {
1231                case(ANDROID_UNINITIALIZED):
1232                    sfplayer_prepare(ap, lockAP);
1233                    // fall through
1234                case(ANDROID_PREPARING):
1235                case(ANDROID_READY):
1236                    if (ap->mSfPlayer != 0) {
1237                        ap->mSfPlayer->play();
1238                    }
1239                    break;
1240                default:
1241                    break;
1242            }
1243            } break;
1244
1245        default:
1246            // checked by caller, should not happen
1247            break;
1248        }
1249        break;
1250#endif
1251    default:
1252        break;
1253    }
1254}
1255
1256
1257//-----------------------------------------------------------------------------
1258void android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1259    IPlay *pPlayItf = &ap->mPlay;
1260    SLuint32 eventFlags = pPlayItf->mEventFlags;
1261    /*switch(ap->mAndroidObjType) {
1262    case AUDIOTRACK_PULL:*/
1263
1264    if (NULL == ap->mAudioTrack) {
1265        return;
1266    }
1267
1268    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1269        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1270                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1271    } else {
1272        // clear marker
1273        ap->mAudioTrack->setMarkerPosition(0);
1274    }
1275
1276    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1277         ap->mAudioTrack->setPositionUpdatePeriod(
1278                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
1279                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1280    } else {
1281        // clear periodic update
1282        ap->mAudioTrack->setPositionUpdatePeriod(0);
1283    }
1284
1285    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1286        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
1287    }
1288
1289    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
1290        // FIXME support SL_PLAYEVENT_HEADMOVING
1291        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
1292            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
1293    }
1294    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1295        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
1296    }
1297
1298}
1299
1300
1301//-----------------------------------------------------------------------------
1302SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
1303    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1304    switch(ap->mAndroidObjType) {
1305    case AUDIOTRACK_PULL:
1306        *pDurMsec = SL_TIME_UNKNOWN;
1307        // FIXME if the data source is not a buffer queue, and the audio data is saved in
1308        //       shared memory with the mixer process, the duration is the size of the buffer
1309        SL_LOGD("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved");
1310        break;
1311#ifndef USE_BACKPORT
1312    case MEDIAPLAYER: {
1313        int64_t durationUsec = SL_TIME_UNKNOWN;
1314        if (ap->mSfPlayer != 0) {
1315            durationUsec = ap->mSfPlayer->getDurationUsec();
1316            *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
1317        }
1318        } break;
1319#endif
1320    default:
1321        break;
1322    }
1323    return SL_RESULT_SUCCESS;
1324}
1325
1326
1327//-----------------------------------------------------------------------------
1328void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
1329    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1330    switch(ap->mAndroidObjType) {
1331    case AUDIOTRACK_PULL:
1332        if ((ap->mSampleRateMilliHz == 0) || (NULL == ap->mAudioTrack)) {
1333            *pPosMsec = 0;
1334        } else {
1335            uint32_t positionInFrames;
1336            ap->mAudioTrack->getPosition(&positionInFrames);
1337            *pPosMsec = ((int64_t)positionInFrames * 1000) /
1338                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1339        }
1340        break;
1341    case MEDIAPLAYER:
1342        if (ap->mSfPlayer != 0) {
1343            *pPosMsec = ap->mSfPlayer->getPositionMsec();
1344        } else {
1345            *pPosMsec = 0;
1346        }
1347        break;
1348    default:
1349        break;
1350    }
1351}
1352
1353
1354//-----------------------------------------------------------------------------
1355void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
1356
1357    switch(ap->mAndroidObjType) {
1358    case AUDIOTRACK_PULL:
1359        break;
1360#ifndef USE_BACKPORT
1361    case MEDIAPLAYER:
1362        if (ap->mSfPlayer != 0) {
1363            ap->mSfPlayer->seek(posMsec);
1364        }
1365        break;
1366#endif
1367    default:
1368        break;
1369    }
1370}
1371
1372
1373//-----------------------------------------------------------------------------
1374void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
1375
1376    if ((MEDIAPLAYER == ap->mAndroidObjType) && (ap->mSfPlayer != 0)) {
1377        ap->mSfPlayer->loop((bool)loopEnable);
1378    }
1379}
1380
1381
1382//-----------------------------------------------------------------------------
1383/*
1384 * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
1385 * the IVolume interface.
1386 * Pre-condition:
1387 *   if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
1388 *   to android_audioPlayer_volumeUpdate()
1389 */
1390static void android_audioPlayer_setMute(CAudioPlayer* ap) {
1391    android::AudioTrack *t = NULL;
1392    switch(ap->mAndroidObjType) {
1393    case AUDIOTRACK_PULL:
1394    case MEDIAPLAYER:
1395        t = ap->mAudioTrack;
1396        break;
1397    default:
1398        break;
1399    }
1400    // when unmuting: volume levels have already been updated in IVolume_SetMute
1401    if (NULL != t) {
1402        t->mute(ap->mMute);
1403    }
1404}
1405
1406
1407//-----------------------------------------------------------------------------
1408SLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) {
1409    android_audioPlayer_updateStereoVolume(ap);
1410    android_audioPlayer_setMute(ap);
1411    return SL_RESULT_SUCCESS;
1412}
1413
1414
1415//-----------------------------------------------------------------------------
1416void android_audioPlayer_bufferQueue_onRefilled(CAudioPlayer *ap) {
1417    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
1418    // queue was stopped when the queue become empty, we restart as soon as a new buffer
1419    // has been enqueued since we're in playing state
1420    if (NULL != ap->mAudioTrack) {
1421        ap->mAudioTrack->start();
1422    }
1423
1424    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
1425    // has received new data, signal it has sufficient data
1426    if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1427        audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_SUFFICIENTDATA,
1428            true);
1429    }
1430}
1431
1432
1433//-----------------------------------------------------------------------------
1434/*
1435 * BufferQueue::Clear
1436 */
1437SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
1438    SLresult result = SL_RESULT_SUCCESS;
1439
1440    switch (ap->mAndroidObjType) {
1441    //-----------------------------------
1442    // AudioTrack
1443    case AUDIOTRACK_PULL:
1444        if (NULL != ap->mAudioTrack) {
1445            ap->mAudioTrack->flush();
1446        }
1447        break;
1448    default:
1449        result = SL_RESULT_INTERNAL_ERROR;
1450        break;
1451    }
1452
1453    return result;
1454}
1455
1456