IPlay.c revision 6a7bf7733e955d4d89204627c34fb357d542a9ec
10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/*
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License.
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License.
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Play implementation */
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//#include "sles_allinclusive.h"
200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
210b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPlayState(SLPlayItf self, SLuint32 state)
220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    switch (state) {
250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_STOPPED:
260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_PAUSED:
270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_PLAYING:
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        break;
290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    default:
300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_exclusive(this);
340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mState = state;
350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (SL_PLAYSTATE_STOPPED == state) {
360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        this->mPosition = (SLmillisecond) 0;
370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        // this->mPositionSamples = 0;
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_ANDROID
406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerSetPlayState(this, state);
426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    interface_unlock_exclusive(this);
456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
480b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPlayState(SLPlayItf self, SLuint32 *pState)
490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pState)
510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 state = this->mState;
550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pState = state;
570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
600b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME: for SNDFILE only, check to see if already know duration
630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // if so, good, otherwise save position,
640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // read quickly to end of file, counting frames,
650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // use sample rate to compute duration, then seek back to current position
660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond duration = this->mDuration;
710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = duration;
736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // initialized to SL_TIME_UNKNOWN in IPlay_init
756a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
790b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
866a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerGetPosition(this, &this->mPosition);
886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond position = this->mPosition;
910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = position;
930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME convert sample units to time units
940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME handle SL_TIME_UNKNOWN
950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
980b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_RegisterCallback(SLPlayItf self, slPlayCallback callback,
990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    void *pContext)
1000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
1030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_exclusive(this);
1040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mCallback = callback;
1050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mContext = pContext;
1060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_exclusive(this);
1070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1100b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
1110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEventFlags = eventFlags;
1166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1176a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1186a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, eventFlags);
1196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1250b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetCallbackEventsMask(SLPlayItf self,
1260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 *pEventFlags)
1270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pEventFlags)
1290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 eventFlags = this->mEventFlags;
1330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pEventFlags = eventFlags;
1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1380b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
1390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = mSec;
1446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, this->mEventFlags);
1476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1530b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_ClearMarkerPosition(SLPlayItf self)
1540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = 0;
1586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1596a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // clearing the marker position can be simulated by using the event mask with a
1616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // cleared flag for the marker
1626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        SLuint32 eventFlags = this->mEventFlags & (~SL_PLAYEVENT_HEADATMARKER);
1636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerUseEventMask(this, eventFlags);
1646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME verify this is still valid for a MediaPlayer
1656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1710b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
1740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond markerPosition = this->mMarkerPosition;
1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = markerPosition;
1800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1830b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
1840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1856a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPositionUpdatePeriod = mSec;
1896a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, this->mEventFlags);
1926a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1936a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1980b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPositionUpdatePeriod(SLPlayItf self,
1990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond *pMsec)
2000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
2010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
2020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
2040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
2050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond positionUpdatePeriod = this->mPositionUpdatePeriod;
2060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
2070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = positionUpdatePeriod;
2080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
2090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
2100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2110b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLPlayItf_ IPlay_Itf = {
2120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetPlayState,
2130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPlayState,
2140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetDuration,
2150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPosition,
2160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_RegisterCallback,
2170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetCallbackEventsMask,
2180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetCallbackEventsMask,
2190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetMarkerPosition,
2200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_ClearMarkerPosition,
2210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetMarkerPosition,
2220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetPositionUpdatePeriod,
2230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPositionUpdatePeriod
2240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
2250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2260b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IPlay_init(void *self)
2270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
2280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
2290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mItf = &IPlay_Itf;
2300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mState = SL_PLAYSTATE_STOPPED;
2310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mDuration = SL_TIME_UNKNOWN;
2320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef NDEBUG
2330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPosition = (SLmillisecond) 0;
2340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // this->mPlay.mPositionSamples = 0;
2350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mCallback = NULL;
2360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mContext = NULL;
2370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEventFlags = 0;
2380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = 0;
2390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPositionUpdatePeriod = 0;
2400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
2410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
242