OSDN Git Service

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