AudioPlayer_to_android.cpp revision b2aeb0f1009555181dabb944fe05901cb6e6f632
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//-----------------------------------------------------------------------------
370void audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
371    if ((NULL != ap->mAudioTrack) && (ap->mAuxEffect != 0)) {
372        android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
373    }
374}
375
376
377//-----------------------------------------------------------------------------
378static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) {
379
380    if (lockAP) { object_lock_exclusive(&ap->mObject); }
381    ap->mAndroidObjState = ANDROID_PREPARING;
382    if (lockAP) { object_unlock_exclusive(&ap->mObject); }
383
384    if (ap->mSfPlayer != 0) {
385        ap->mSfPlayer->prepare();
386    }
387}
388
389//-----------------------------------------------------------------------------
390// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
391// from a URI or FD, for prepare and prefetch events
392static void sfplayer_handlePrefetchEvent(const int event, const int data1, void* user) {
393    if (NULL == user) {
394        return;
395    }
396
397    CAudioPlayer *ap = (CAudioPlayer *)user;
398    //SL_LOGV("received event %d, data %d from SfAudioPlayer", event, data1);
399    switch(event) {
400
401    case(android::AVPlayer::kEventPrepared): {
402
403        if (PLAYER_SUCCESS != data1) {
404            object_lock_exclusive(&ap->mObject);
405
406            ap->mAudioTrack = NULL;
407            ap->mNumChannels = 0;
408            ap->mSampleRateMilliHz = 0;
409            ap->mAndroidObjState = ANDROID_UNINITIALIZED;
410
411            object_unlock_exclusive(&ap->mObject);
412
413            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
414            //  indicate a prefetch error, so we signal it by sending simulataneously two events:
415            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
416            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
417            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
418            if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
419                break;
420            }
421
422            slPrefetchCallback callback = NULL;
423            void* callbackPContext = NULL;
424
425            interface_lock_exclusive(&ap->mPrefetchStatus);
426            ap->mPrefetchStatus.mLevel = 0;
427            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
428            if ((ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE)
429                    && (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE)) {
430                callback = ap->mPrefetchStatus.mCallback;
431                callbackPContext = ap->mPrefetchStatus.mContext;
432            }
433            interface_unlock_exclusive(&ap->mPrefetchStatus);
434
435            // callback with no lock held
436            if (NULL != callback) {
437                (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
438                        SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
439            }
440
441
442        } else {
443            object_lock_exclusive(&ap->mObject);
444
445            if (A_PLR_URIFD == ap->mAndroidObjType) {
446                ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
447                ap->mNumChannels = ap->mSfPlayer->getNumChannels();
448                ap->mSampleRateMilliHz =
449                        android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
450                ap->mSfPlayer->startPrefetch_async();
451                // update the new track with the current settings
452                audioPlayer_auxEffectUpdate(ap);
453                android_audioPlayer_useEventMask(ap);
454                android_audioPlayer_volumeUpdate(ap);
455                android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/);
456            } else if (A_PLR_TS_ABQ) {
457                SL_LOGI("Received SfPlayer::kEventPrepared from AVPlayer for CAudioPlayer %p", ap);
458            }
459
460            ap->mAndroidObjState = ANDROID_READY;
461
462            object_unlock_exclusive(&ap->mObject);
463        }
464
465    } break;
466
467    case(android::SfPlayer::kEventNewAudioTrack): {
468        object_lock_exclusive(&ap->mObject);
469#if 1
470        // SfPlayer has a new AudioTrack, update our pointer copy and configure the new one before
471        // starting to use it
472#else
473        // SfPlayer has a new AudioTrack, delete the old one and configure the new one before
474        // starting to use it
475
476        if (NULL != ap->mAudioTrack) {
477            delete ap->mAudioTrack;
478            ap->mAudioTrack = NULL;
479        }
480#endif
481        ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
482        ap->mNumChannels = ap->mSfPlayer->getNumChannels();
483        ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
484
485        // update the new track with the current settings
486        audioPlayer_auxEffectUpdate(ap);
487        android_audioPlayer_useEventMask(ap);
488        android_audioPlayer_volumeUpdate(ap);
489        android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/);
490
491        object_unlock_exclusive(&ap->mObject);
492    } break;
493
494    case(android::SfPlayer::kEventPrefetchFillLevelUpdate): {
495        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
496            break;
497        }
498        slPrefetchCallback callback = NULL;
499        void* callbackPContext = NULL;
500
501        // SLPrefetchStatusItf callback or no callback?
502        interface_lock_exclusive(&ap->mPrefetchStatus);
503        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
504            callback = ap->mPrefetchStatus.mCallback;
505            callbackPContext = ap->mPrefetchStatus.mContext;
506        }
507        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
508        interface_unlock_exclusive(&ap->mPrefetchStatus);
509
510        // callback with no lock held
511        if (NULL != callback) {
512            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
513                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
514        }
515    } break;
516
517    case(android::SfPlayer::kEventPrefetchStatusChange): {
518        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
519            break;
520        }
521        slPrefetchCallback callback = NULL;
522        void* callbackPContext = NULL;
523
524        // SLPrefetchStatusItf callback or no callback?
525        object_lock_exclusive(&ap->mObject);
526        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
527            callback = ap->mPrefetchStatus.mCallback;
528            callbackPContext = ap->mPrefetchStatus.mContext;
529        }
530        if (data1 >= android::SfPlayer::kStatusIntermediate) {
531            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
532            // FIXME estimate fill level better?
533            ap->mPrefetchStatus.mLevel = 1000;
534            ap->mAndroidObjState = ANDROID_READY;
535        } else if (data1 < android::SfPlayer::kStatusIntermediate) {
536            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
537            // FIXME estimate fill level better?
538            ap->mPrefetchStatus.mLevel = 0;
539        }
540        object_unlock_exclusive(&ap->mObject);
541
542        // callback with no lock held
543        if (NULL != callback) {
544            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
545        }
546        } break;
547
548    case(android::SfPlayer::kEventEndOfStream): {
549        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
550        if ((NULL != ap->mAudioTrack) && (!ap->mSeek.mLoopEnabled)) {
551            ap->mAudioTrack->stop();
552        }
553        } break;
554
555    default:
556        break;
557    }
558}
559
560
561//-----------------------------------------------------------------------------
562SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
563{
564    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
565    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
566    //--------------------------------------
567    // Sink check:
568    //     currently only OutputMix sinks are supported, regardless of the data source
569    if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) {
570        SL_LOGE("Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX");
571        return SL_RESULT_PARAMETER_INVALID;
572    }
573
574    //--------------------------------------
575    // Source check:
576    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
577    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
578
579    switch (locatorType) {
580    //------------------
581    //   Buffer Queues
582    case SL_DATALOCATOR_BUFFERQUEUE:
583    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
584        {
585        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
586
587        // Buffer format
588        switch (formatType) {
589        //     currently only PCM buffer queues are supported,
590        case SL_DATAFORMAT_PCM: {
591            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
592            switch (df_pcm->numChannels) {
593            case 1:
594            case 2:
595                break;
596            default:
597                // this should have already been rejected by checkDataFormat
598                SL_LOGE("Cannot create audio player: unsupported " \
599                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
600                return SL_RESULT_CONTENT_UNSUPPORTED;
601            }
602            switch (df_pcm->samplesPerSec) {
603            case SL_SAMPLINGRATE_8:
604            case SL_SAMPLINGRATE_11_025:
605            case SL_SAMPLINGRATE_12:
606            case SL_SAMPLINGRATE_16:
607            case SL_SAMPLINGRATE_22_05:
608            case SL_SAMPLINGRATE_24:
609            case SL_SAMPLINGRATE_32:
610            case SL_SAMPLINGRATE_44_1:
611            case SL_SAMPLINGRATE_48:
612                break;
613            case SL_SAMPLINGRATE_64:
614            case SL_SAMPLINGRATE_88_2:
615            case SL_SAMPLINGRATE_96:
616            case SL_SAMPLINGRATE_192:
617            default:
618                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
619                    (unsigned) df_pcm->samplesPerSec);
620                return SL_RESULT_CONTENT_UNSUPPORTED;
621            }
622            switch (df_pcm->bitsPerSample) {
623            case SL_PCMSAMPLEFORMAT_FIXED_8:
624                // FIXME We should support this
625                //SL_LOGE("Cannot create audio player: unsupported 8-bit data");
626                //return SL_RESULT_CONTENT_UNSUPPORTED;
627            case SL_PCMSAMPLEFORMAT_FIXED_16:
628                break;
629                // others
630            default:
631                // this should have already been rejected by checkDataFormat
632                SL_LOGE("Cannot create audio player: unsupported sample bit depth %lu",
633                        (SLuint32)df_pcm->bitsPerSample);
634                return SL_RESULT_CONTENT_UNSUPPORTED;
635            }
636            switch (df_pcm->containerSize) {
637            case 8:
638            case 16:
639                break;
640                // others
641            default:
642                SL_LOGE("Cannot create audio player: unsupported container size %u",
643                    (unsigned) df_pcm->containerSize);
644                return SL_RESULT_CONTENT_UNSUPPORTED;
645            }
646            switch (df_pcm->channelMask) {
647                // FIXME needs work
648            default:
649                break;
650            }
651            switch (df_pcm->endianness) {
652            case SL_BYTEORDER_LITTLEENDIAN:
653                break;
654            case SL_BYTEORDER_BIGENDIAN:
655                SL_LOGE("Cannot create audio player: unsupported big-endian byte order");
656                return SL_RESULT_CONTENT_UNSUPPORTED;
657                // native is proposed but not yet in spec
658            default:
659                SL_LOGE("Cannot create audio player: unsupported byte order %u",
660                    (unsigned) df_pcm->endianness);
661                return SL_RESULT_CONTENT_UNSUPPORTED;
662            }
663            } //case SL_DATAFORMAT_PCM
664            break;
665        case SL_DATAFORMAT_MIME:
666        case XA_DATAFORMAT_RAWIMAGE:
667            SL_LOGE("Cannot create audio player with buffer queue data source "
668                "without SL_DATAFORMAT_PCM format");
669            return SL_RESULT_CONTENT_UNSUPPORTED;
670        default:
671            // invalid data format is detected earlier
672            assert(false);
673            return SL_RESULT_INTERNAL_ERROR;
674        } // switch (formatType)
675        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
676        break;
677    //------------------
678    //   URI
679    case SL_DATALOCATOR_URI:
680        {
681        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
682        if (NULL == dl_uri->URI) {
683            return SL_RESULT_PARAMETER_INVALID;
684        }
685        // URI format
686        switch (formatType) {
687        case SL_DATAFORMAT_MIME:
688            break;
689        case SL_DATAFORMAT_PCM:
690        case XA_DATAFORMAT_RAWIMAGE:
691            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
692                "SL_DATAFORMAT_MIME format");
693            return SL_RESULT_CONTENT_UNSUPPORTED;
694        } // switch (formatType)
695        } // case SL_DATALOCATOR_URI
696        break;
697    //------------------
698    //   File Descriptor
699    case SL_DATALOCATOR_ANDROIDFD:
700        {
701        // fd is already non null
702        switch (formatType) {
703        case SL_DATAFORMAT_MIME:
704            break;
705        case SL_DATAFORMAT_PCM:
706            // FIXME implement
707            SL_LOGD("[ FIXME implement PCM FD data sources ]");
708            break;
709        case XA_DATAFORMAT_RAWIMAGE:
710            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
711                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
712            return SL_RESULT_CONTENT_UNSUPPORTED;
713        default:
714            // invalid data format is detected earlier
715            assert(false);
716            return SL_RESULT_INTERNAL_ERROR;
717        } // switch (formatType)
718        } // case SL_DATALOCATOR_ANDROIDFD
719        break;
720    //------------------
721    //   Stream
722    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
723        {
724        } // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
725        break;
726    //------------------
727    //   Address
728    case SL_DATALOCATOR_ADDRESS:
729    case SL_DATALOCATOR_IODEVICE:
730    case SL_DATALOCATOR_OUTPUTMIX:
731    case XA_DATALOCATOR_NATIVEDISPLAY:
732    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
733        SL_LOGE("Cannot create audio player with data locator type 0x%x", (unsigned) locatorType);
734        return SL_RESULT_CONTENT_UNSUPPORTED;
735    default:
736        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
737                (unsigned) locatorType);
738        return SL_RESULT_PARAMETER_INVALID;
739    }// switch (locatorType)
740
741    return SL_RESULT_SUCCESS;
742}
743
744
745
746//-----------------------------------------------------------------------------
747static void audioTrack_callBack_uri(int event, void* user, void *info) {
748    // EVENT_MORE_DATA needs to be handled with priority over the other events
749    // because it will be called the most often during playback
750    if (event == android::AudioTrack::EVENT_MORE_DATA) {
751        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
752        // set size to 0 to signal we're not using the callback to write more data
753        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
754        pBuff->size = 0;
755    } else if (NULL != user) {
756        switch (event) {
757            case (android::AudioTrack::EVENT_MARKER) :
758                audioTrack_handleMarker_lockPlay((CAudioPlayer *)user);
759                break;
760            case (android::AudioTrack::EVENT_NEW_POS) :
761                audioTrack_handleNewPos_lockPlay((CAudioPlayer *)user);
762                break;
763            case (android::AudioTrack::EVENT_UNDERRUN) :
764                audioTrack_handleUnderrun_lockPlay((CAudioPlayer *)user);
765                break;
766            case (android::AudioTrack::EVENT_BUFFER_END) :
767            case (android::AudioTrack::EVENT_LOOP_END) :
768                break;
769            default:
770                SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
771                        (CAudioPlayer *)user);
772                break;
773        }
774    }
775}
776
777//-----------------------------------------------------------------------------
778// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
779// from a buffer queue.
780static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
781    CAudioPlayer *ap = (CAudioPlayer *)user;
782    void * callbackPContext = NULL;
783    switch(event) {
784
785    case (android::AudioTrack::EVENT_MORE_DATA) : {
786        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
787        slBufferQueueCallback callback = NULL;
788        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
789        // retrieve data from the buffer queue
790        interface_lock_exclusive(&ap->mBufferQueue);
791        if (ap->mBufferQueue.mState.count != 0) {
792            //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count);
793            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
794
795            BufferHeader *oldFront = ap->mBufferQueue.mFront;
796            BufferHeader *newFront = &oldFront[1];
797
798            // FIXME handle 8bit based on buffer format
799            short *pSrc = (short*)((char *)oldFront->mBuffer
800                    + ap->mBufferQueue.mSizeConsumed);
801            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
802                // can't consume the whole or rest of the buffer in one shot
803                ap->mBufferQueue.mSizeConsumed += pBuff->size;
804                // leave pBuff->size untouched
805                // consume data
806                // FIXME can we avoid holding the lock during the copy?
807                memcpy (pBuff->i16, pSrc, pBuff->size);
808            } else {
809                // finish consuming the buffer or consume the buffer in one shot
810                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
811                ap->mBufferQueue.mSizeConsumed = 0;
812
813                if (newFront ==
814                        &ap->mBufferQueue.mArray
815                            [ap->mBufferQueue.mNumBuffers + 1])
816                {
817                    newFront = ap->mBufferQueue.mArray;
818                }
819                ap->mBufferQueue.mFront = newFront;
820
821                ap->mBufferQueue.mState.count--;
822                ap->mBufferQueue.mState.playIndex++;
823
824                // consume data
825                // FIXME can we avoid holding the lock during the copy?
826                memcpy (pBuff->i16, pSrc, pBuff->size);
827
828                // data has been consumed, and the buffer queue state has been updated
829                // we will notify the client if applicable
830                callback = ap->mBufferQueue.mCallback;
831                // save callback data
832                callbackPContext = ap->mBufferQueue.mContext;
833            }
834        } else { // empty queue
835            // signal no data available
836            pBuff->size = 0;
837
838            // signal we're at the end of the content, but don't pause (see note in function)
839            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
840
841            // signal underflow to prefetch status itf
842            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
843                audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_UNDERFLOW,
844                    false);
845            }
846
847            // stop the track so it restarts playing faster when new data is enqueued
848            ap->mAudioTrack->stop();
849        }
850        interface_unlock_exclusive(&ap->mBufferQueue);
851        // notify client
852        if (NULL != callback) {
853            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
854        }
855    }
856    break;
857
858    case (android::AudioTrack::EVENT_MARKER) :
859        audioTrack_handleMarker_lockPlay(ap);
860        break;
861
862    case (android::AudioTrack::EVENT_NEW_POS) :
863        audioTrack_handleNewPos_lockPlay(ap);
864        break;
865
866    case (android::AudioTrack::EVENT_UNDERRUN) :
867        audioTrack_handleUnderrun_lockPlay(ap);
868        break;
869
870    default:
871        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
872        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
873                (CAudioPlayer *)user);
874        break;
875    }
876}
877
878
879//-----------------------------------------------------------------------------
880SLresult android_audioPlayer_create(
881        CAudioPlayer *pAudioPlayer) {
882
883    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
884    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
885    SLresult result = SL_RESULT_SUCCESS;
886
887    //--------------------------------------
888    // Sink check:
889    // currently only OutputMix sinks are supported
890    // this has already been verified in sles_to_android_CheckAudioPlayerSourceSink
891    // SLuint32 locatorType = *(SLuint32 *)pAudioSnk->pLocator;
892    // if (SL_DATALOCATOR_OUTPUTMIX == locatorType) {
893    // }
894
895    //--------------------------------------
896    // Source check:
897    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
898    switch (locatorType) {
899    //   -----------------------------------
900    //   Buffer Queue to AudioTrack
901    case SL_DATALOCATOR_BUFFERQUEUE:
902    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
903        pAudioPlayer->mAndroidObjType = A_PLR_PCM_BQ;
904        pAudioPlayer->mpLock = new android::Mutex();
905        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
906        break;
907    //   -----------------------------------
908    //   URI or FD to MediaPlayer
909    case SL_DATALOCATOR_URI:
910    case SL_DATALOCATOR_ANDROIDFD:
911        pAudioPlayer->mAndroidObjType = A_PLR_URIFD;
912        pAudioPlayer->mpLock = new android::Mutex();
913        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
914        break;
915    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
916        pAudioPlayer->mAndroidObjType = A_PLR_TS_ABQ;
917        pAudioPlayer->mpLock = new android::Mutex();
918        pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
919        break;
920    default:
921        pAudioPlayer->mAndroidObjType = INVALID_TYPE;
922        pAudioPlayer->mpLock = NULL;
923        pAudioPlayer->mPlaybackRate.mCapabilities = 0;
924        result = SL_RESULT_PARAMETER_INVALID;
925        break;
926    }
927
928    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
929    pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
930    pAudioPlayer->mAudioTrack = NULL;
931    // no longer needed, as placement new (explicit constructor) already does this
932    // pAudioPlayer->mSfPlayer.clear();
933
934    pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
935
936    pAudioPlayer->mAmplFromVolLevel = 1.0f;
937    pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
938    pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
939    pAudioPlayer->mDirectLevel = 0; // no attenuation
940    pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
941    pAudioPlayer->mAuxSendLevel = 0;
942
943    // initialize interface-specific fields that can be used regardless of whether the interface
944    // is exposed on the AudioPlayer or not
945    // (section no longer applicable, as all previous initializations were the same as the defaults)
946
947    return result;
948
949}
950
951
952//-----------------------------------------------------------------------------
953SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
954        const void *pConfigValue, SLuint32 valueSize) {
955
956    SLresult result = SL_RESULT_SUCCESS;
957
958    if (NULL == ap) {
959        result = SL_RESULT_INTERNAL_ERROR;
960    } else if (NULL == pConfigValue) {
961        SL_LOGE(ERROR_CONFIG_NULL_PARAM);
962        result = SL_RESULT_PARAMETER_INVALID;
963
964    } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
965
966        // stream type
967        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
968            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
969            result = SL_RESULT_PARAMETER_INVALID;
970        } else {
971            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
972        }
973
974    } else {
975        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
976        result = SL_RESULT_PARAMETER_INVALID;
977    }
978
979    return result;
980}
981
982
983//-----------------------------------------------------------------------------
984SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
985        SLuint32* pValueSize, void *pConfigValue) {
986
987    SLresult result = SL_RESULT_SUCCESS;
988
989    if (NULL == ap) {
990        return SL_RESULT_INTERNAL_ERROR;
991    } else if (NULL == pValueSize) {
992        SL_LOGE(ERROR_CONFIG_NULL_PARAM);
993        result = SL_RESULT_PARAMETER_INVALID;
994
995    } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
996
997        // stream type
998        if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
999            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1000            result = SL_RESULT_PARAMETER_INVALID;
1001        } else {
1002            *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
1003            if (NULL != pConfigValue) {
1004                result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
1005            }
1006        }
1007
1008    } else {
1009        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1010        result = SL_RESULT_PARAMETER_INVALID;
1011    }
1012
1013    return result;
1014}
1015
1016
1017//-----------------------------------------------------------------------------
1018SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1019
1020    SLresult result = SL_RESULT_SUCCESS;
1021    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1022
1023    switch (pAudioPlayer->mAndroidObjType) {
1024    //-----------------------------------
1025    // AudioTrack
1026    case A_PLR_PCM_BQ:
1027        {
1028        // initialize platform-specific CAudioPlayer fields
1029
1030        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
1031                pAudioPlayer->mDynamicSource.mDataSource;
1032        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1033                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1034
1035        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1036
1037        pAudioPlayer->mAudioTrack = new android::AudioTrack(
1038                pAudioPlayer->mStreamType,                           // streamType
1039                sampleRate,                                          // sampleRate
1040                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
1041                sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
1042                                                                     //channel mask
1043                0,                                                   // frameCount (here min)
1044                0,                                                   // flags
1045                audioTrack_callBack_pullFromBuffQueue,               // callback
1046                (void *) pAudioPlayer,                               // user
1047                0      // FIXME find appropriate frame count         // notificationFrame
1048                , pAudioPlayer->mSessionId
1049                );
1050        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
1051        if (status != android::NO_ERROR) {
1052            SL_LOGE("AudioTrack::initCheck status %u", status);
1053            result = SL_RESULT_CONTENT_UNSUPPORTED;
1054        }
1055
1056        // initialize platform-independent CAudioPlayer fields
1057
1058        pAudioPlayer->mNumChannels = df_pcm->numChannels;
1059        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
1060
1061        pAudioPlayer->mAndroidObjState = ANDROID_READY;
1062        } break;
1063    //-----------------------------------
1064    // MediaPlayer
1065    case A_PLR_URIFD: {
1066        object_lock_exclusive(&pAudioPlayer->mObject);
1067
1068        pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1069        pAudioPlayer->mNumChannels = 0;
1070        pAudioPlayer->mSampleRateMilliHz = 0;
1071        pAudioPlayer->mAudioTrack = NULL;
1072
1073        AudioPlayback_Parameters app;
1074        app.sessionId = pAudioPlayer->mSessionId;
1075        app.streamType = pAudioPlayer->mStreamType;
1076        app.trackcb = audioTrack_callBack_uri;
1077        app.trackcbUser = (void *) pAudioPlayer;
1078
1079        pAudioPlayer->mSfPlayer = new android::SfPlayer(&app);
1080        pAudioPlayer->mSfPlayer->setNotifListener(sfplayer_handlePrefetchEvent,
1081                        (void*)pAudioPlayer /*notifUSer*/);
1082        pAudioPlayer->mSfPlayer->armLooper();
1083
1084        object_unlock_exclusive(&pAudioPlayer->mObject);
1085
1086        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1087            case SL_DATALOCATOR_URI:
1088                pAudioPlayer->mSfPlayer->setDataSource(
1089                        (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1090                break;
1091            case SL_DATALOCATOR_ANDROIDFD: {
1092                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1093                pAudioPlayer->mSfPlayer->setDataSource(
1094                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1095                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1096                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1097                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1098                } break;
1099            default:
1100                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1101                break;
1102        }
1103
1104        } break;
1105   //-----------------------------------
1106   // StreamPlayer
1107   case A_PLR_TS_ABQ: {
1108        object_lock_exclusive(&pAudioPlayer->mObject);
1109
1110        android_StreamPlayer_realize_l(pAudioPlayer, sfplayer_handlePrefetchEvent,
1111                (void*)pAudioPlayer);
1112
1113        object_unlock_exclusive(&pAudioPlayer->mObject);
1114        } break;
1115    //-----------------------------------
1116    default:
1117        SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType);
1118        result = SL_RESULT_INTERNAL_ERROR;
1119        break;
1120    }
1121
1122
1123    // proceed with effect initialization
1124    // initialize EQ
1125    // FIXME use a table of effect descriptors when adding support for more effects
1126    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1127            sizeof(effect_uuid_t)) == 0) {
1128        SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1129        android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1130    }
1131    // initialize BassBoost
1132    if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1133            sizeof(effect_uuid_t)) == 0) {
1134        SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1135        android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1136    }
1137    // initialize Virtualizer
1138    if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1139               sizeof(effect_uuid_t)) == 0) {
1140        SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1141        android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1142    }
1143
1144    // initialize EffectSend
1145    // FIXME initialize EffectSend
1146
1147    return result;
1148}
1149
1150
1151//-----------------------------------------------------------------------------
1152SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1153    SLresult result = SL_RESULT_SUCCESS;
1154    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1155    switch (pAudioPlayer->mAndroidObjType) {
1156    //-----------------------------------
1157    // AudioTrack
1158    case A_PLR_PCM_BQ:
1159        // We own the audio track for PCM buffer queue players
1160        if (pAudioPlayer->mAudioTrack != NULL) {
1161            pAudioPlayer->mAudioTrack->stop();
1162            delete pAudioPlayer->mAudioTrack;
1163            pAudioPlayer->mAudioTrack = NULL;
1164        }
1165        break;
1166    //-----------------------------------
1167    // MediaPlayer
1168    case A_PLR_URIFD:
1169        // We don't own this audio track, SfPlayer does
1170        pAudioPlayer->mAudioTrack = NULL;
1171        // FIXME might no longer be needed since we call explicit destructor
1172        if (pAudioPlayer->mSfPlayer != 0) {
1173            pAudioPlayer->mSfPlayer.clear();
1174        }
1175        break;
1176    //-----------------------------------
1177    // StreamPlayer
1178    case A_PLR_TS_ABQ:
1179        android_StreamPlayer_destroy(pAudioPlayer);
1180        break;
1181    //-----------------------------------
1182    default:
1183        SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType);
1184        result = SL_RESULT_INTERNAL_ERROR;
1185        break;
1186    }
1187
1188    // FIXME might not be needed
1189    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
1190
1191    // explicit destructor
1192    pAudioPlayer->mSfPlayer.~sp();
1193    pAudioPlayer->mAuxEffect.~sp();
1194
1195    if (pAudioPlayer->mpLock != NULL) {
1196        delete pAudioPlayer->mpLock;
1197        pAudioPlayer->mpLock = NULL;
1198    }
1199
1200    return result;
1201}
1202
1203
1204//-----------------------------------------------------------------------------
1205SLresult android_audioPlayer_setPlayRate(CAudioPlayer *ap, SLpermille rate, bool lockAP) {
1206    SLresult result = SL_RESULT_SUCCESS;
1207    uint32_t contentRate = 0;
1208    switch(ap->mAndroidObjType) {
1209    case A_PLR_PCM_BQ:
1210    case A_PLR_URIFD: {
1211        // get the content sample rate
1212        if (lockAP) { object_lock_shared(&ap->mObject); }
1213        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1214        if (lockAP) { object_unlock_shared(&ap->mObject); }
1215        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
1216        if (ap->mAudioTrack != NULL) {
1217            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
1218        }
1219        }
1220        break;
1221
1222    default:
1223        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1224        result = SL_RESULT_INTERNAL_ERROR;
1225        break;
1226    }
1227    return result;
1228}
1229
1230
1231//-----------------------------------------------------------------------------
1232// called with no lock held
1233SLresult android_audioPlayer_setPlaybackRateBehavior(CAudioPlayer *ap,
1234        SLuint32 constraints) {
1235    SLresult result = SL_RESULT_SUCCESS;
1236    switch(ap->mAndroidObjType) {
1237    case A_PLR_PCM_BQ:
1238    case A_PLR_URIFD:
1239        if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
1240            result = SL_RESULT_FEATURE_UNSUPPORTED;
1241        }
1242        break;
1243    default:
1244        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1245        result = SL_RESULT_INTERNAL_ERROR;
1246        break;
1247    }
1248    return result;
1249}
1250
1251
1252//-----------------------------------------------------------------------------
1253// called with no lock held
1254SLresult android_audioPlayer_getCapabilitiesOfRate(CAudioPlayer *ap,
1255        SLuint32 *pCapabilities) {
1256    switch(ap->mAndroidObjType) {
1257    case A_PLR_PCM_BQ:
1258    case A_PLR_URIFD:
1259        *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
1260        break;
1261    default:
1262        *pCapabilities = 0;
1263        break;
1264    }
1265    return SL_RESULT_SUCCESS;
1266}
1267
1268
1269//-----------------------------------------------------------------------------
1270void android_audioPlayer_setPlayState(CAudioPlayer *ap, bool lockAP) {
1271
1272    if (lockAP) { object_lock_shared(&ap->mObject); }
1273    SLuint32 playState = ap->mPlay.mState;
1274    AndroidObject_state objState = ap->mAndroidObjState;
1275    if (lockAP) { object_unlock_shared(&ap->mObject); }
1276
1277    switch(ap->mAndroidObjType) {
1278    case A_PLR_PCM_BQ:
1279        switch (playState) {
1280        case SL_PLAYSTATE_STOPPED:
1281            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1282            if (NULL != ap->mAudioTrack) {
1283                ap->mAudioTrack->stop();
1284            }
1285            break;
1286        case SL_PLAYSTATE_PAUSED:
1287            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1288            if (NULL != ap->mAudioTrack) {
1289                ap->mAudioTrack->pause();
1290            }
1291            break;
1292        case SL_PLAYSTATE_PLAYING:
1293            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1294            if (NULL != ap->mAudioTrack) {
1295                ap->mAudioTrack->start();
1296            }
1297            break;
1298        default:
1299            // checked by caller, should not happen
1300            break;
1301        }
1302        break;
1303
1304    case A_PLR_URIFD:
1305        switch (playState) {
1306        case SL_PLAYSTATE_STOPPED: {
1307            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1308            if (ap->mSfPlayer != 0) {
1309                ap->mSfPlayer->stop();
1310            }
1311            } break;
1312        case SL_PLAYSTATE_PAUSED: {
1313            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1314            switch(objState) {
1315                case(ANDROID_UNINITIALIZED):
1316                    sfplayer_prepare(ap, lockAP);
1317                    break;
1318                case(ANDROID_PREPARING):
1319                    break;
1320                case(ANDROID_READY):
1321                    if (ap->mSfPlayer != 0) {
1322                        ap->mSfPlayer->pause();
1323                    }
1324                    break;
1325                default:
1326                    break;
1327            }
1328            } break;
1329        case SL_PLAYSTATE_PLAYING: {
1330            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1331            switch(objState) {
1332                case(ANDROID_UNINITIALIZED):
1333                    sfplayer_prepare(ap, lockAP);
1334                    // fall through
1335                case(ANDROID_PREPARING):
1336                case(ANDROID_READY):
1337                    if (ap->mSfPlayer != 0) {
1338                        ap->mSfPlayer->play();
1339                    }
1340                    break;
1341                default:
1342                    break;
1343            }
1344            } break;
1345
1346        default:
1347            // checked by caller, should not happen
1348            break;
1349        }
1350        break;
1351
1352    case A_PLR_TS_ABQ: {
1353        android::AVPlayer* avp = (android::AVPlayer*) ap->mStreamPlayer.get();
1354        if (avp != NULL) {
1355            android_Player_setPlayState(avp, playState, &(ap->mAndroidObjState));
1356        }
1357        }
1358        break;
1359
1360    default:
1361        break;
1362    }
1363}
1364
1365
1366//-----------------------------------------------------------------------------
1367void android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1368    IPlay *pPlayItf = &ap->mPlay;
1369    SLuint32 eventFlags = pPlayItf->mEventFlags;
1370    /*switch(ap->mAndroidObjType) {
1371    case A_PLR_PCM_BQ:*/
1372
1373    if (NULL == ap->mAudioTrack) {
1374        return;
1375    }
1376
1377    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1378        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1379                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1380    } else {
1381        // clear marker
1382        ap->mAudioTrack->setMarkerPosition(0);
1383    }
1384
1385    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1386         ap->mAudioTrack->setPositionUpdatePeriod(
1387                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
1388                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1389    } else {
1390        // clear periodic update
1391        ap->mAudioTrack->setPositionUpdatePeriod(0);
1392    }
1393
1394    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1395        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
1396    }
1397
1398    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
1399        // FIXME support SL_PLAYEVENT_HEADMOVING
1400        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
1401            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
1402    }
1403    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1404        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
1405    }
1406
1407}
1408
1409
1410//-----------------------------------------------------------------------------
1411SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
1412    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1413    switch(ap->mAndroidObjType) {
1414    case A_PLR_PCM_BQ:
1415        *pDurMsec = SL_TIME_UNKNOWN;
1416        // FIXME if the data source is not a buffer queue, and the audio data is saved in
1417        //       shared memory with the mixer process, the duration is the size of the buffer
1418        SL_LOGD("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved");
1419        break;
1420    case A_PLR_URIFD: {
1421        int64_t durationUsec = SL_TIME_UNKNOWN;
1422        if (ap->mSfPlayer != 0) {
1423            durationUsec = ap->mSfPlayer->getDurationUsec();
1424            *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
1425        }
1426        } break;
1427    default:
1428        break;
1429    }
1430    return SL_RESULT_SUCCESS;
1431}
1432
1433
1434//-----------------------------------------------------------------------------
1435void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
1436    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1437    switch(ap->mAndroidObjType) {
1438    case A_PLR_PCM_BQ:
1439        if ((ap->mSampleRateMilliHz == 0) || (NULL == ap->mAudioTrack)) {
1440            *pPosMsec = 0;
1441        } else {
1442            uint32_t positionInFrames;
1443            ap->mAudioTrack->getPosition(&positionInFrames);
1444            *pPosMsec = ((int64_t)positionInFrames * 1000) /
1445                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1446        }
1447        break;
1448    case A_PLR_URIFD:
1449        if (ap->mSfPlayer != 0) {
1450            *pPosMsec = ap->mSfPlayer->getPositionMsec();
1451        } else {
1452            *pPosMsec = 0;
1453        }
1454        break;
1455    default:
1456        break;
1457    }
1458}
1459
1460
1461//-----------------------------------------------------------------------------
1462void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
1463
1464    switch(ap->mAndroidObjType) {
1465    case A_PLR_PCM_BQ:
1466        break;
1467    case A_PLR_URIFD:
1468        if (ap->mSfPlayer != 0) {
1469            ap->mSfPlayer->seek(posMsec);
1470        }
1471        break;
1472    default:
1473        break;
1474    }
1475}
1476
1477
1478//-----------------------------------------------------------------------------
1479void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
1480
1481    if ((A_PLR_URIFD == ap->mAndroidObjType) && (ap->mSfPlayer != 0)) {
1482        ap->mSfPlayer->loop((bool)loopEnable);
1483    }
1484}
1485
1486
1487//-----------------------------------------------------------------------------
1488/*
1489 * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
1490 * the IVolume interface.
1491 * Pre-condition:
1492 *   if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
1493 *   to android_audioPlayer_volumeUpdate()
1494 */
1495static void android_audioPlayer_setMute(CAudioPlayer* ap) {
1496    android::AudioTrack *t = NULL;
1497    switch(ap->mAndroidObjType) {
1498    case A_PLR_PCM_BQ:
1499    case A_PLR_URIFD:
1500        t = ap->mAudioTrack;
1501        break;
1502    default:
1503        break;
1504    }
1505    // when unmuting: volume levels have already been updated in IVolume_SetMute
1506    if (NULL != t) {
1507        t->mute(ap->mMute);
1508    }
1509}
1510
1511
1512//-----------------------------------------------------------------------------
1513SLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) {
1514    android_audioPlayer_updateStereoVolume(ap);
1515    android_audioPlayer_setMute(ap);
1516    return SL_RESULT_SUCCESS;
1517}
1518
1519
1520//-----------------------------------------------------------------------------
1521void android_audioPlayer_bufferQueue_onRefilled(CAudioPlayer *ap) {
1522    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
1523    // queue was stopped when the queue become empty, we restart as soon as a new buffer
1524    // has been enqueued since we're in playing state
1525    if (NULL != ap->mAudioTrack) {
1526        ap->mAudioTrack->start();
1527    }
1528
1529    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
1530    // has received new data, signal it has sufficient data
1531    if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1532        audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_SUFFICIENTDATA,
1533            true);
1534    }
1535}
1536
1537
1538//-----------------------------------------------------------------------------
1539/*
1540 * BufferQueue::Clear
1541 */
1542SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
1543    SLresult result = SL_RESULT_SUCCESS;
1544
1545    switch (ap->mAndroidObjType) {
1546    //-----------------------------------
1547    // AudioTrack
1548    case A_PLR_PCM_BQ:
1549        if (NULL != ap->mAudioTrack) {
1550            ap->mAudioTrack->flush();
1551        }
1552        break;
1553    default:
1554        result = SL_RESULT_INTERNAL_ERROR;
1555        break;
1556    }
1557
1558    return result;
1559}
1560
1561
1562//-----------------------------------------------------------------------------
1563void android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) {
1564    if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mStreamPlayer != 0)) {
1565        android_StreamPlayer_androidBufferQueue_registerCallback(ap->mStreamPlayer.get(),
1566                ap->mAndroidBufferQueue.mCallback,
1567                ap->mAndroidBufferQueue.mContext,
1568                (const void*)&(ap->mAndroidBufferQueue.mItf));
1569    }
1570}
1571
1572//-----------------------------------------------------------------------------
1573void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
1574    if (ap->mAndroidObjType == A_PLR_TS_ABQ) {
1575        android_StreamPlayer_clear_l(ap);
1576    }
1577}
1578
1579void android_audioPlayer_androidBufferQueue_enqueue_l(CAudioPlayer *ap,
1580        SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData) {
1581    if (ap->mAndroidObjType == A_PLR_TS_ABQ) {
1582        android_StreamPlayer_enqueue_l(ap, bufferId, length, event, pData);
1583    }
1584}
1585