17e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi/* 27e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 37e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * 47e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 57e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * you may not use this file except in compliance with the License. 67e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * You may obtain a copy of the License at 77e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * 87e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 97e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * 107e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 117e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 127e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * See the License for the specific language governing permissions and 147e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi * limitations under the License. 157e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi */ 167e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 177e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi/* \file COutputMix.c OutputMix class */ 187e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 197e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi#include "sles_allinclusive.h" 207e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 217e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 227e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi/** \brief Hook called by Object::Realize when an output mix is realized */ 237e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 247e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel TriviSLresult COutputMix_Realize(void *self, SLboolean async) 257e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi{ 267e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi SLresult result = SL_RESULT_SUCCESS; 277e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 287e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi#ifdef ANDROID 29bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten COutputMix *thiz = (COutputMix *) self; 30bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = android_outputMix_realize(thiz, async); 317e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi#endif 327e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 337e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi return result; 347e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi} 357e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 367e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 377e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi/** \brief Hook called by Object::Resume when an output mix is resumed */ 38928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 397e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel TriviSLresult COutputMix_Resume(void *self, SLboolean async) 407e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi{ 41928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten return SL_RESULT_SUCCESS; 427e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi} 437e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 447e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 457e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi/** \brief Hook called by Object::Destroy when an output mix is destroyed */ 467e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi 477e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivivoid COutputMix_Destroy(void *self) 487e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi{ 497e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi#ifdef ANDROID 50bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten COutputMix *thiz = (COutputMix *) self; 51bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_outputMix_destroy(thiz); 527e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi#endif 537e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi} 54928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 55928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 56928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Hook called by Object::Destroy before an output mix is about to be destroyed */ 57928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten 581d081e49a10543018e1ae33792bd3d30504719baGlenn Kastenpredestroy_t COutputMix_PreDestroy(void *self) 59928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten{ 60f51dba65751107c930759938775b75531ec1f330Glenn Kasten // Ignore destroy requests if there are any players attached to this output mix 61f51dba65751107c930759938775b75531ec1f330Glenn Kasten COutputMix *outputMix = (COutputMix *) self; 62f51dba65751107c930759938775b75531ec1f330Glenn Kasten // See design document for explanation 63f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (0 == outputMix->mObject.mStrongRefCount) { 64a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifdef USE_OUTPUTMIXEXT 65b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // We only support a single active output mix per engine, so check if this is the active mix 66b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn Kasten IEngine *thisEngine = &outputMix->mObject.mEngine->mEngine; 67b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten interface_lock_exclusive(thisEngine); 68b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten bool thisIsTheActiveOutputMix = false; 69b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (outputMix == thisEngine->mOutputMix) { 70b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten thisIsTheActiveOutputMix = true; 71f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 72b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten interface_unlock_exclusive(thisEngine); 73b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (thisIsTheActiveOutputMix) { 74b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // Tell the asynchronous mixer callback that we want to destroy the output mix 75b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten outputMix->mOutputMixExt.mDestroyRequested = true; 76b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten while (outputMix->mOutputMixExt.mDestroyRequested) { 77b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten object_cond_wait(&outputMix->mObject); 78b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 79a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#ifdef USE_SDL 80b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // Mixer callback has acknowledged our request and unlinked output mix from engine. 81b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // Disable SDL_callback from being called periodically by SDL's internal thread. 82b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten SDL_PauseAudio(1); 83b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#endif 84b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 85f51dba65751107c930759938775b75531ec1f330Glenn Kasten#endif 861d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten return predestroy_ok; 87f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 88f51dba65751107c930759938775b75531ec1f330Glenn Kasten SL_LOGE("Object::Destroy(%p) for OutputMix ignored; %u players attached", outputMix, 89f51dba65751107c930759938775b75531ec1f330Glenn Kasten outputMix->mObject.mStrongRefCount); 901d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten return predestroy_error; 91928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten} 92