IPlay.c revision bcc5c7225e3b7a1dbf2e9e830987f69167acf06f
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 19979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include "sles_allinclusive.h" 20979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten 21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 220b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPlayState(SLPlayItf self, SLuint32 state) 230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 24ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (state) { 270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_STOPPED: 280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_PAUSED: 290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_PLAYING: 30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten { 31bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten unsigned attr = ATTR_NONE; 33ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 3494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef USE_OUTPUTMIXEXT 35bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ? 36bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (CAudioPlayer *) thiz->mThis : NULL; 3794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef USE_OUTPUTMIXEXT 40bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten for (;; interface_cond_wait(thiz)) { 414b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 424b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // We are comparing the old state (left) vs. new state (right). 434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // Note that the old state is 3 bits wide, but new state is only 2 bits wide. 444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // That is why the old state is on the left and new state is on the right. 45bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten switch ((thiz->mState << 2) | state) { 464b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 474b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_STOPPED: 484b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_PAUSED: 494b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_PLAYING: 504b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // no-op 514b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 524b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 534b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_PLAYING: 544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_PLAYING: 554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attr = ATTR_TRANSPORT; 564b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // set enqueue attribute if queue is non-empty and state becomes PLAYING 574b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if ((NULL != audioPlayer) && (audioPlayer->mBufferQueue.mFront != 584b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mBufferQueue.mRear)) { 594b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attr |= ATTR_ENQUEUE; 604b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 614b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // fall through 624b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 634b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_PAUSED: 644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_PAUSED: 654b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // easy 66bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = state; 674b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 684b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 694b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_STOPPED: 704b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // either spurious wakeup, or someone else requested same transition 714b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 724b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PAUSED: 744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PLAYING: 754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // wait for other guy to finish his transition, then retry ours 764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_STOPPED: 794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_STOPPED: 804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // tell mixer to stop, then wait for mixer to acknowledge the request to stop 81bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = SL_PLAYSTATE_STOPPING; 824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 844b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten default: 854b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // unexpected state 864b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten assert(SL_BOOLEAN_FALSE); 874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten result = SL_RESULT_INTERNAL_ERROR; 884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 934b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 944b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#else 954b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // Here life looks easy for an Android, but there are other troubles in play land 96bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = state; 974b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attr = ATTR_TRANSPORT; 984b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 991d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten // SL_LOGD("set play state %ld", state); 100bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, attr); 101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1054b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1120b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPlayState(SLPlayItf self, SLuint32 *pState) 1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pState) { 117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 119bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 120bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_peek(thiz); 121bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 state = thiz->mState; 122bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_peek(thiz); 123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 1244b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef USE_OUTPUTMIXEXT 1254b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten switch (state) { 1264b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_STOPPED: // as is 1274b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_PAUSED: 1284b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_PLAYING: 1294b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1304b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_STOPPING: // these states require re-mapping 1314b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten state = SL_PLAYSTATE_STOPPED; 1324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1334b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten default: // impossible 1344b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten assert(SL_BOOLEAN_FALSE); 1354b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten state = SL_PLAYSTATE_STOPPED; 1364b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten result = SL_RESULT_INTERNAL_ERROR; 1374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1384b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 1404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten *pState = state; 141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 143ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1470b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetDuration(SLPlayItf self, SLmillisecond *pMsec) 1480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 152ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 155bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // even though this is a getter, it can modify state due to caching 157bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 158bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond duration = thiz->mDuration; 159ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if ((SL_TIME_UNKNOWN == duration) && 161bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz))) { 162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLmillisecond temp; 163bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = android_audioPlayer_getDuration(thiz, &temp); 164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 165ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten duration = temp; 166bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDuration = duration; 167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 168e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 169e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 1708c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // will be set by containing AudioPlayer or MidiPlayer object at Realize, if known, 1718c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // otherwise the duration will be updated each time a new maximum position is detected 172dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi#endif 173bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = duration; 175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1810b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPosition(SLPlayItf self, SLmillisecond *pMsec) 1820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 187ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 188bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLmillisecond position; 190bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_shared(thiz); 191ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Android does not use the mPosition field for audio players 193bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 194bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_audioPlayer_getPosition(thiz, &position); 195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // note that we do not cache the position 1968c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } else { 197bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten position = thiz->mPosition; 1988c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 199e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // on other platforms we depend on periodic updates to the current position 201bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten position = thiz->mPosition; 2028c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // if a seek is pending, then lie about current position so the seek appears synchronous 203bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 204bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis; 2058c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SLmillisecond pos = audioPlayer->mSeek.mPos; 2068c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (SL_TIME_UNKNOWN != pos) { 2078c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten position = pos; 2088c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2098c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif 211bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_shared(thiz); 212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = position; 213ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 220d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_RegisterCallback(SLPlayItf self, slPlayCallback callback, void *pContext) 2210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 222ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 223ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 224bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 225bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 226bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mCallback = callback; 227bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mContext = pContext; 228e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // omits _attributes b/c noone cares deeply enough about these fields to need quick notification 229bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 230ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 231ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 232ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 2360b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags) 2370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 238ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 239ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 2408c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (eventFlags & ~(SL_PLAYEVENT_HEADATEND | SL_PLAYEVENT_HEADATMARKER | 2418c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADMOVING | SL_PLAYEVENT_HEADSTALLED)) { 2428c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 2438c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } else { 244bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 245bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 246bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mEventFlags != eventFlags) { 2478c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 2488c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // enabling the "head at new position" play event will postpone the next update event 249bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (!(thiz->mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) && 2508c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten (eventFlags & SL_PLAYEVENT_HEADATNEWPOS)) { 251bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 2528c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2538c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 254bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEventFlags = eventFlags; 255bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 2568c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } else 257bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 2588c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten result = SL_RESULT_SUCCESS; 2598c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 261ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 264ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 265d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_GetCallbackEventsMask(SLPlayItf self, SLuint32 *pEventFlags) 2660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 267ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 268ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 269ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pEventFlags) { 270ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 271ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 272bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 273bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_peek(thiz); 274bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 eventFlags = thiz->mEventFlags; 275bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_peek(thiz); 276ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEventFlags = eventFlags; 277ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 278ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 279ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 280ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 283ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 2840b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec) 2850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 286ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 287ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 288bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 289bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 290bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mMarkerPosition != mSec) { 291bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mMarkerPosition = mSec; 292bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 293e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } else 294bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 295ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3010b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_ClearMarkerPosition(SLPlayItf self) 3020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 305bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 306bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 307ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 308bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 3093b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi // clearing the marker position is equivalent to setting the marker at 0 310bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mMarkerPosition = 0; 3116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi } 3126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif 313bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 314ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 315ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 316ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 319ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3200b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec) 3210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 322ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 323ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 324ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 325ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 326ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 327bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 328bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_peek(thiz); 329bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond markerPosition = thiz->mMarkerPosition; 330bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_peek(thiz); 331ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = markerPosition; 332ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 333ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 334ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3390b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec) 3400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 341ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 342ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 343ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (0 == mSec) { 344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 345ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 346bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 347bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 348bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mPositionUpdatePeriod != mSec) { 349bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPositionUpdatePeriod = mSec; 350ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 351bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 352bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten // result = android_audioPlayer_useEventMask(thiz, thiz->mEventFlags); 353ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 3546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif 3558c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 356bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 357bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis; 3588c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SLuint32 frameUpdatePeriod = ((long long) mSec * 3598c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten (long long) audioPlayer->mSampleRateMilliHz) / 1000000LL; 3608c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (0 == frameUpdatePeriod) 3618c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten frameUpdatePeriod = ~0; 362bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFrameUpdatePeriod = frameUpdatePeriod; 3638c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // setting a new update period postpones the next callback 364bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 3658c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 3668c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 367bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 368ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else 369bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 370ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 371ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 372ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 373ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 376ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 377d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_GetPositionUpdatePeriod(SLPlayItf self, SLmillisecond *pMsec) 3780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 379ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 380ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 381ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 382ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 383ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 384bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 385bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_peek(thiz); 386bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond positionUpdatePeriod = thiz->mPositionUpdatePeriod; 387bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_peek(thiz); 388ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = positionUpdatePeriod; 389ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 390ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 391ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 392ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 395ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3960b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLPlayItf_ IPlay_Itf = { 3970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetPlayState, 3980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPlayState, 3990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetDuration, 4000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPosition, 4010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_RegisterCallback, 4020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetCallbackEventsMask, 4030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetCallbackEventsMask, 4040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetMarkerPosition, 4050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_ClearMarkerPosition, 4060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetMarkerPosition, 4070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetPositionUpdatePeriod, 4080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPositionUpdatePeriod 4090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 4100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4110b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IPlay_init(void *self) 4120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 413bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 414bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mItf = &IPlay_Itf; 415bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = SL_PLAYSTATE_STOPPED; 416bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDuration = SL_TIME_UNKNOWN; // will be set by containing player object 417bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPosition = (SLmillisecond) 0; 418bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mCallback = NULL; 419bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mContext = NULL; 420bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEventFlags = 0; 421bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mMarkerPosition = 0; 422bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPositionUpdatePeriod = 1000; 4238c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 424bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFrameUpdatePeriod = 0; // because we don't know the sample rate yet 425bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLastSeekPosition = 0; 426bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSinceLastSeek = 0; 427bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 4288c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 4290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 430