IEngine.c revision 70c49ae2867094072a4365423417ea452bf82231
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/* Engine implementation */ 180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 19979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include "sles_allinclusive.h" 20979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten 21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 22daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 23daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 26ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 27a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & USE_PROFILES_OPTIONAL 28928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) { 29ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 31ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pDevice = NULL; 32ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 33ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE); 34c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCLEDDevice_class) { 35c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 36c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 37c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds, 38c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceRequired, &exposedMask); 39c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 40ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 41bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CLEDDevice *thiz = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self); 42bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 43ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 44ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 45bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDeviceID = deviceID; 46bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 47f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new LED object 48bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pDevice = &thiz->mObject.mItf; 49ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 50ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 51ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 527a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 537a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 547a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 55ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 56ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 59ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 60daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 61daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 63ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 64ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 65a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & USE_PROFILES_OPTIONAL 66928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) { 67ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 68ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 69ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pDevice = NULL; 70ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE); 72c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCVibraDevice_class) { 73c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 74c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 75c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCVibraDevice_class, numInterfaces, 76c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 77c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 79bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CVibraDevice *thiz = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self); 80bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 82ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 83bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDeviceID = deviceID; 84bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 85f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new vibra object 86bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pDevice = &thiz->mObject.mItf; 87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 88ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 89ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 907a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 917a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 927a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 980b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 1000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 1010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pPlayer) { 105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pPlayer = NULL; 108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER); 110c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten assert(NULL != pCAudioPlayer_class); 111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = checkInterfaces(pCAudioPlayer_class, numInterfaces, 112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Construct our new AudioPlayer instance 116bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *thiz = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self); 117bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 120b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten 121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten do { 122daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Initialize private fields not associated with an interface 124a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 125a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Default data source in case of failure in checkDataSource 126bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 127bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL; 128a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 129a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Default data sink in case of failure in checkDataSink 130bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 131bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL; 132a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 133a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Default is no per-channel mute or solo 134bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mMuteMask = 0; 135bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSoloMask = 0; 136a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 137f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // Will be set soon for PCM buffer queues, or later by platform-specific code 138f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // during Realize or Prefetch 139bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mNumChannels = 0; 140bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSampleRateMilliHz = 0; 141daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 142a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // More default values, in case destructor needs to be called early 143bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDirectLevel = 0; 144a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#ifdef USE_OUTPUTMIXEXT 145bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mTrack = NULL; 146bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mGains[0] = 1.0f; 147bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mGains[1] = 1.0f; 148bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDestroyRequested = SL_BOOLEAN_FALSE; 149a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#endif 150a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#ifdef USE_SNDFILE 151bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSndFile.mPathname = NULL; 152bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSndFile.mSNDFILE = NULL; 153bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mSndFile.mSfInfo, 0, sizeof(SF_INFO)); 154bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mSndFile.mMutex, 0, sizeof(pthread_mutex_t)); 155bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSndFile.mEOF = SL_BOOLEAN_FALSE; 156bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSndFile.mWhich = 0; 157bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(thiz->mSndFile.mBuffer, 0, sizeof(thiz->mSndFile.mBuffer)); 158a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#endif 159a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#ifdef ANDROID 160a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // extra safe initializations of pointers, in case of incomplete construction 161bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mpLock = NULL; 162bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAudioTrack = NULL; 163a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // placement new (explicit constructor) 16413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // FIXME unnecessary once those fields are encapsulated in one class, rather 16513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // than a structure 166bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (void) new (&thiz->mSfPlayer) android::sp<android::SfPlayer>(); 167bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (void) new (&thiz->mAuxEffect) android::sp<android::AudioEffect>(); 16813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi (void) new (&thiz->mAPlayer) android::sp<android::GenericPlayer>(); 169a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#endif 170a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Check the source and sink parameters against generic constraints, 172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // and make a local copy of all parameters in case other application threads 173ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // change memory concurrently. 174daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 175bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource, 17694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS | 17794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_BUFFERQUEUE 17894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef ANDROID 17994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE 180c869defb7c0dd6f4e45ad26abb0f8ccc960152deJean-Michel Trivi | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE 18194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 18294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM); 183c869defb7c0dd6f4e45ad26abb0f8ccc960152deJean-Michel Trivi 1843c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 1853c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1863c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1873c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 188bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink, 18913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi DATALOCATOR_MASK_OUTPUTMIX // for playback 19013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#ifdef ANDROID 19113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE // for decode to a BQ 19213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi | DATALOCATOR_MASK_BUFFERQUEUE // for decode to a BQ 19313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#endif 19413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi , DATAFORMAT_MASK_NULL 19513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#ifdef ANDROID 19613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi | DATAFORMAT_MASK_PCM // for decode to PCM 19713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#endif 19813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi ); 1993c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 2013c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 202daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 203f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // It would be unsafe to ever refer to the application pointers again 204f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten pAudioSrc = NULL; 205f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten pAudioSnk = NULL; 206f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten 207f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // Check that the requested interfaces are compatible with the data source 208bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkSourceFormatVsInterfacesCompatibility(&thiz->mDataSource, 209104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten pCAudioPlayer_class, exposedMask); 2103c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 211ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 2123c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 213daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 21413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // copy the buffer queue count from source locator (for playback) / from the 21513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // sink locator (for decode on ANDROID build) to the buffer queue interface 21618abcc4b70fab1f84d6fbebac3a8e34480a6c4d3Glenn Kasten // we have already range-checked the value down to a smaller width 21713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi SLuint16 nbBuffers = 0; 218d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi bool usesAdvancedBufferHeaders = false; 219bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten switch (thiz->mDataSource.mLocator.mLocatorType) { 22001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_BUFFERQUEUE: 22101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#ifdef ANDROID 22201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 22301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten#endif 22413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mBufferQueue.numBuffers; 225bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(SL_DATAFORMAT_PCM == thiz->mDataSource.mFormat.mFormatType); 226bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mNumChannels = thiz->mDataSource.mFormat.mPCM.numChannels; 227bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSampleRateMilliHz = thiz->mDataSource.mFormat.mPCM.samplesPerSec; 22801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten break; 229d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#ifdef ANDROID 230d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 231d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mABQ.numBuffers; 232d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi usesAdvancedBufferHeaders = true; 233d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers; 234d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi break; 235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#endif 23601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten default: 23713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi nbBuffers = 0; 23801e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten break; 23901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten } 24013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#ifdef ANDROID 24113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi switch(thiz->mDataSink.mLocator.mLocatorType) { 24213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi case SL_DATALOCATOR_BUFFERQUEUE: 24313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 24413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi nbBuffers = thiz->mDataSink.mLocator.mBufferQueue.numBuffers; 24513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi assert(SL_DATAFORMAT_PCM == thiz->mDataSink.mFormat.mFormatType); 24613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi thiz->mNumChannels = thiz->mDataSink.mFormat.mPCM.numChannels; 24713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi thiz->mSampleRateMilliHz = thiz->mDataSink.mFormat.mPCM.samplesPerSec; 24813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi break; 24913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi default: 25013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // leave nbBuffers unchanged 25113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi break; 25213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi } 25313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#endif 25413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi thiz->mBufferQueue.mNumBuffers = nbBuffers; 2554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 256ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // check the audio source and sink parameters against platform support 257ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 258bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = android_audioPlayer_checkSourceSink(thiz); 259928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 261928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 2620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 263acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten 2640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_SNDFILE 265bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = SndFile_checkAudioPlayerSourceSink(thiz); 266928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 267ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 268928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 2690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif 2700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 2710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_OUTPUTMIXEXT 272bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = IOutputMixExt_checkAudioPlayerSourceSink(thiz); 273928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 274ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 275928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 276daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten#endif 2770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 278ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Allocate memory for buffer queue 279d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (usesAdvancedBufferHeaders) { 280d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // locator is SL_DATALOCATOR_ANDROIDBUFFERQUEUE 281d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // Avoid possible integer overflow during multiplication; this arbitrary 282d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // maximum is big enough to not interfere with real applications, but 283d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // small enough to not overflow. 284d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (thiz->mAndroidBufferQueue.mNumBuffers >= 256) { 285d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 286d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi break; 287d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 288d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *) 289d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi malloc( (thiz->mAndroidBufferQueue.mNumBuffers + 1) 290d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi * sizeof(AdvancedBufferHeader)); 291d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (NULL == thiz->mAndroidBufferQueue.mBufferArray) { 292d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 293d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi break; 294d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } else { 29570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 29670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // initialize ABQ buffer type 29770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // assert below has been checked in android_audioPlayer_checkSourceSink 29870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi assert(SL_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType); 29970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (SL_CONTAINERTYPE_MPEG_TS == 30070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mDataSource.mFormat.mMIME.containerType) { 30170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts; 30270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { 30370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid; 30470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi SL_LOGE("Invalid buffer type in Android Buffer Queue"); 30570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 30670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 30770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 30870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // initialize ABQ memory 309d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi for (SLuint16 i=0 ; i<(thiz->mAndroidBufferQueue.mNumBuffers + 1) ; 310d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi i++) { 311d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataBuffer = NULL; 312d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataSize = 0; 313d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataSizeConsumed = 0; 31470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi switch (thiz->mAndroidBufferQueue.mBufferType) { 31570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi case kAndroidBufferTypeMpeg2Ts: 31670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData. 31770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mTsCmdCode = ANDROID_MP2TSEVENT_NONE; 31870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData. 31970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mPts = 0; 32070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 32170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi default: 32270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 32370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 32470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 325d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 326d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mFront = 327d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray; 328d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mRear = 329d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray; 330d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 331d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } else { 332d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // locator is SL_DATALOCATOR_BUFFERQUEUE 333d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 334ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // inline allocation of circular mArray, up to a typical max 335bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) { 336bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical; 337ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Avoid possible integer overflow during multiplication; this arbitrary 339ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // maximum is big enough to not interfere with real applications, but 340ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // small enough to not overflow. 341bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mBufferQueue.mNumBuffers >= 256) { 342ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 343ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 345bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue. 346d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi mNumBuffers + 1) * sizeof(BufferHeader)); 347bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz->mBufferQueue.mArray) { 348ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 349ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 350ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 351ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 352bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray; 353bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray; 354d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 355ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 356d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // used to store the data source of our audio player 357d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource; 358ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 359d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // platform-specific initialization 360ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#ifdef ANDROID 361d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi android_audioPlayer_create(thiz); 362ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#endif 3630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 364ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } while (0); 365daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 366e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten if (SL_RESULT_SUCCESS != result) { 367bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Destroy(&thiz->mObject.mItf); 368f51dba65751107c930759938775b75531ec1f330Glenn Kasten } else { 369bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 370f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new audio player object 371bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pPlayer = &thiz->mObject.mItf; 372e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten } 373daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten 374ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 375ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 376acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten 377ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 378ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 379ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 382ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 383ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kastenstatic SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder, 384ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 385ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 3860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 387ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 388ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 389a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID) 390ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pRecorder) { 391ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 392ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 393ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pRecorder = NULL; 394ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 395ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER); 396c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCAudioRecorder_class) { 397c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 398c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 399c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCAudioRecorder_class, numInterfaces, 400c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 401c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 4023af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 403ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 404ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 405ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Construct our new AudioRecorder instance 406bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioRecorder *thiz = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask, 4073af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi self); 408bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 409ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 410ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 411ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 412ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten do { 413f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten 414f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // Initialize fields not associated with any interface 415f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten 416a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Default data source in case of failure in checkDataSource 417bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 418bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL; 419a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 420a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // Default data sink in case of failure in checkDataSink 421bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 422bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL; 423a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 424f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // These fields are set to real values by 425f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // android_audioRecorder_checkSourceSinkSupport. Note that the data sink is 426f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // always PCM buffer queue, so we know the channel count and sample rate early. 427bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mNumChannels = 0; 428bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mSampleRateMilliHz = 0; 429f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten#ifdef ANDROID 430bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAudioRecord = NULL; 431bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mRecordSource = android::AUDIO_SOURCE_DEFAULT; 432f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten#endif 433712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi 434ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Check the source and sink parameters, and make a local copy of all parameters 435bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource, 43694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL); 437928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 438ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 439928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 440bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink, 44194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_URI 44294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef ANDROID 44394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE 44494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 44594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM 44694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten ); 447928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 448ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 449928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 450ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 451f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten // It would be unsafe to ever refer to the application pointers again 452f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten pAudioSrc = NULL; 453f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten pAudioSnk = NULL; 454f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten 4553af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // check the audio source and sink parameters against platform support 4563af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi#ifdef ANDROID 457bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = android_audioRecorder_checkSourceSinkSupport(thiz); 4583af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 459a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten SL_LOGE("Cannot create AudioRecorder: invalid source or sink"); 4603af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 4613af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 4623af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi#endif 4633af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 4644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef ANDROID 4659e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten // Allocate memory for buffer queue 466bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType; 46701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) { 468bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mNumBuffers = 469bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDataSink.mLocator.mBufferQueue.numBuffers; 4703af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // inline allocation of circular Buffer Queue mArray, up to a typical max 471bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) { 472bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical; 4733af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } else { 4743af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // Avoid possible integer overflow during multiplication; this arbitrary 4753af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // maximum is big enough to not interfere with real applications, but 4763af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // small enough to not overflow. 477bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mBufferQueue.mNumBuffers >= 256) { 4783af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 4793af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 4803af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 481bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue. 4823af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi mNumBuffers + 1) * sizeof(BufferHeader)); 483bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz->mBufferQueue.mArray) { 4843af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 4853af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi break; 4863af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 4873af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 488bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray; 489bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray; 4903af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi } 4914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 4923af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi 4933af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi // platform-specific initialization 4943af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi#ifdef ANDROID 495bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_audioRecorder_create(thiz); 4963af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi#endif 497ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 498ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } while (0); 499ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 500928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if (SL_RESULT_SUCCESS != result) { 501bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Destroy(&thiz->mObject.mItf); 502f51dba65751107c930759938775b75531ec1f330Glenn Kasten } else { 503bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 504f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new audio recorder object 505bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pRecorder = &thiz->mObject.mItf; 506928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 507ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 508ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 509ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 510ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 511ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 5127a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5137a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5147a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 515ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 516ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 5170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 5180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 519ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 5200b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 5210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 5220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 5230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 5240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 525ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 526ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 527a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE) 528928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) { 529ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 530ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 531ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pPlayer = NULL; 532ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 533ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER); 534c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCMidiPlayer_class) { 535c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 536c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 537c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCMidiPlayer_class, numInterfaces, 538c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 539c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 540ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 541bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self); 542bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 543ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 544ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 54594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#if 0 54694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE 54794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL 54894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL 54994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pVibra", pVibra, NULL | IODEVICE, NULL 55094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pLEDArray", pLEDArray, NULL | IODEVICE, NULL 55194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 5529e0f457f2809f5f062ac052d4a304e8996b49a80Glenn Kasten // a fake value - why not use value from IPlay_init? what does CT check for? 553bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPlay.mDuration = 0; 554bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 555f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new MIDI player object 556bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pPlayer = &thiz->mObject.mItf; 557ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 558ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 559ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 5607a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5617a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5627a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 563ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 564ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 5650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 5660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 567ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 5680b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 569d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 5700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 571ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 572ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 573a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & USE_PROFILES_GAME 574ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pListener) { 575ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 576ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 577ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pListener = NULL; 578ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 579ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER); 580c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCListener_class) { 581c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 582c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 583c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCListener_class, numInterfaces, 584c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 585c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 586ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 587bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self); 588bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 589ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 590ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 591bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 592f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new 3D listener object 593bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pListener = &thiz->mObject.mItf; 594ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 595ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 596ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 5977a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5987a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5997a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 600ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 601ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 6020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 6030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 604ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 605d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces, 606d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 6070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 608ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 609ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 610a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & USE_PROFILES_GAME 611ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pGroup) { 612ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 613ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 614ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pGroup = NULL; 615ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 616ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP); 617c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pC3DGroup_class) { 618c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 619c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 620c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pC3DGroup_class, numInterfaces, 621c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 622c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 623ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 624bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self); 625bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 626ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 627ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 628bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mMemberMask = 0; 629bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 630f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new 3D group object 631bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pGroup = &thiz->mObject.mItf; 632ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 633ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 634ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 6357a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 6367a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 6377a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 638ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 639ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 6400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 6410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 642ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 64300d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kastenstatic SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces, 64400d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 6450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 646ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 647ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 648ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMix) { 649ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 650ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 651ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMix = NULL; 652ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 653ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX); 654c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten assert(NULL != pCOutputMix_class); 655ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = checkInterfaces(pCOutputMix_class, numInterfaces, 656ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 657ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 658bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self); 659bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 660ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 661ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 66243e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi#ifdef ANDROID 663bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_outputMix_create(thiz); 66443e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi#endif 665f51dba65751107c930759938775b75531ec1f330Glenn Kasten#ifdef USE_SDL 666bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IEngine *thisEngine = &thiz->mObject.mEngine->mEngine; 667f51dba65751107c930759938775b75531ec1f330Glenn Kasten interface_lock_exclusive(thisEngine); 668f51dba65751107c930759938775b75531ec1f330Glenn Kasten bool unpause = false; 669f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (NULL == thisEngine->mOutputMix) { 670bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thisEngine->mOutputMix = thiz; 671f51dba65751107c930759938775b75531ec1f330Glenn Kasten unpause = true; 672f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 673f51dba65751107c930759938775b75531ec1f330Glenn Kasten interface_unlock_exclusive(thisEngine); 674f51dba65751107c930759938775b75531ec1f330Glenn Kasten#endif 675bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 676f51dba65751107c930759938775b75531ec1f330Glenn Kasten#ifdef USE_SDL 677f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (unpause) { 678f51dba65751107c930759938775b75531ec1f330Glenn Kasten // Enable SDL_callback to be called periodically by SDL's internal thread 679f51dba65751107c930759938775b75531ec1f330Glenn Kasten SDL_PauseAudio(0); 680f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 681f51dba65751107c930759938775b75531ec1f330Glenn Kasten#endif 682f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new output mix object 683bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pMix = &thiz->mObject.mItf; 684ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 685ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 686ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 687ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 688ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 6890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 6900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 691ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 692d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor, 693d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 6940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLboolean *pInterfaceRequired) 6950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 696ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 697ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 698a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC) 699ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMetadataExtractor) { 700ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 701ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 702ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMetadataExtractor = NULL; 703ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned exposedMask; 704ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *pCMetadataExtractor_class = 705ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR); 706c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten if (NULL == pCMetadataExtractor_class) { 707c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 708c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } else { 709c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten result = checkInterfaces(pCMetadataExtractor_class, numInterfaces, 710c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten pInterfaceIds, pInterfaceRequired, &exposedMask); 711c2b9d79c4b59caff965076f445f5a735a360b084Glenn Kasten } 712ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 713bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CMetadataExtractor *thiz = (CMetadataExtractor *) 714ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten construct(pCMetadataExtractor_class, exposedMask, self); 715bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 716ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_MEMORY_FAILURE; 717ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 71894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#if 0 71994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pDataSource", pDataSource, NONE, NONE 72094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 721bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 722f51dba65751107c930759938775b75531ec1f330Glenn Kasten // return the new metadata extractor object 723bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pMetadataExtractor = &thiz->mObject.mItf; 724ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 725ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 726ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 727ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 7287a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 7297a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 7307a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 731ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 732ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 7330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 7340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 735ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 736d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject, 737d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten void *pParameters, SLuint32 objectID, SLuint32 numInterfaces, 738d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 7390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 740ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 741ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 742ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pObject) { 743ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 744ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 745ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pObject = NULL; 746ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 747ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 748ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 749ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 7500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 7510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 752ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 7530b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 7540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 7550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 756ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 757ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 758ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pNumSupportedInterfaces) { 759ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 760ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 761bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const ClassTable *clazz = objectIDtoClass(objectID); 762bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == clazz) { 763ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 764ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 765ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLuint32 count = 0; 766ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLuint32 i; 767bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten for (i = 0; i < clazz->mInterfaceCount; ++i) { 768bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten switch (clazz->mInterfaces[i].mInterface) { 769c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 770104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 771c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 7725e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 773c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 774ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten ++count; 775c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 776c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 777c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 778c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 779c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 780c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 781c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 782c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 783ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pNumSupportedInterfaces = count; 784ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 785ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 786ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 787ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 788ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE; 7890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 7900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 791ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 7920b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 7930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 7940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 795ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 796ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 797ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pInterfaceId) { 798ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 799ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 800ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pInterfaceId = NULL; 801bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten const ClassTable *clazz = objectIDtoClass(objectID); 802bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == clazz) { 803ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 804ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 805ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; // will be reset later 806ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLuint32 i; 807bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten for (i = 0; i < clazz->mInterfaceCount; ++i) { 808bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten switch (clazz->mInterfaces[i].mInterface) { 809c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_IMPLICIT: 810104c000a6f36b871ca11e0394db1e5217f374cafGlenn Kasten case INTERFACE_IMPLICIT_PREREALIZE: 811c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_EXPLICIT: 8125e3b06982dbf1eae237cc74326e66d51d3cdd664Glenn Kasten case INTERFACE_EXPLICIT_PREREALIZE: 813c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_DYNAMIC: 814c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 815c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten case INTERFACE_UNAVAILABLE: 816ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten continue; 817c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten default: 818c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten assert(false); 819c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten break; 820c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten } 821ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (index == 0) { 822bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH]; 823ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 824ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 825ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 826ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten --index; 827ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 828a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 829a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten } 830ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 831ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 8320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 8330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 834ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 835b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kastenstatic const char * const extensionNames[] = { 836b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#ifdef ANDROID 837105e1b828063c07e000e642d225881bdcd93f4deGlenn Kasten "ANDROID_SDK_LEVEL_12", // Android 3.0+ aka "Honeycomb MR1" 838b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#else 839b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten "WILHELM_DESKTOP", 840b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#endif 841b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten}; 842b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten 843b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten 844ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kastenstatic SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions) 8450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 846ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 847ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 848ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pNumExtensions) { 849ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 850ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 851b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 852ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 853ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 854ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 855ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 8560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 8570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 858ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 8590b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 8600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 8610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 862ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 863ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 864b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (NULL == pNameLength) { 865b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 866b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else { 867b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten size_t actualNameLength; 868b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 869b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (index >= numExtensions) { 870b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten actualNameLength = 0; 871b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 872b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else { 873b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten const char *extensionName = extensionNames[index]; 874b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten actualNameLength = strlen(extensionName) + 1; 875b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (NULL == pExtensionName) { 876b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // application is querying the name length in order to allocate a buffer 877b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_SUCCESS; 878b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else { 879b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten SLint16 availableNameLength = *pNameLength; 880b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (0 >= availableNameLength) { 881b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // there is not even room for the terminating NUL 882b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_BUFFER_INSUFFICIENT; 883b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else if (actualNameLength > (size_t) availableNameLength) { 884b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten // "no invalid strings are written. That is, the null-terminator always exists" 885b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1); 886b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten pExtensionName[(size_t) availableNameLength - 1] = '\0'; 887b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_BUFFER_INSUFFICIENT; 888b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else { 889b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten memcpy(pExtensionName, extensionName, actualNameLength); 890b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_SUCCESS; 891b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 892b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 893b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 894b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten *pNameLength = actualNameLength; 895b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 896ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 897ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 8980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 8990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 900ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 9010b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngine_IsExtensionSupported(SLEngineItf self, 9020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten const SLchar *pExtensionName, SLboolean *pSupported) 9030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 904ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 905ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 906b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (NULL == pSupported) { 907ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 908ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 909b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten SLboolean isSupported = SL_BOOLEAN_FALSE; 910b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (NULL == pExtensionName) { 911b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 912b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } else { 913b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 914b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten unsigned i; 915b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten for (i = 0; i < numExtensions; ++i) { 916b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten if (!strcmp((const char *) pExtensionName, extensionNames[i])) { 917b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten isSupported = SL_BOOLEAN_TRUE; 918b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten break; 919b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 920b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 921b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten result = SL_RESULT_SUCCESS; 922b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten } 923b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten *pSupported = isSupported; 924ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 925ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 926ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 9270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 9280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 929ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 9300b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLEngineItf_ IEngine_Itf = { 9310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateLEDDevice, 9320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateVibraDevice, 9330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateAudioPlayer, 9340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateAudioRecorder, 9350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateMidiPlayer, 9360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateListener, 9370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_Create3DGroup, 9380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateOutputMix, 9390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateMetadataExtractor, 9400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_CreateExtensionObject, 9410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QueryNumSupportedInterfaces, 9420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QuerySupportedInterfaces, 9430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QueryNumSupportedExtensions, 9440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_QuerySupportedExtension, 9450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IEngine_IsExtensionSupported 9460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 9470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 9480b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IEngine_init(void *self) 9490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 950bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IEngine *thiz = (IEngine *) self; 951bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mItf = &IEngine_Itf; 952a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten // mLossOfControlGlobal is initialized in slCreateEngine 95300d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 954bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOutputMix = NULL; 95500d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 956bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mInstanceCount = 1; // ourself 957bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mInstanceMask = 0; 958bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mChangedMask = 0; 9590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten unsigned i; 960928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten for (i = 0; i < MAX_INSTANCE; ++i) { 961bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mInstances[i] = NULL; 962928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten } 963bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mShutdown = SL_BOOLEAN_FALSE; 964bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mShutdownAck = SL_BOOLEAN_FALSE; 9650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 966a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten 967a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenvoid IEngine_deinit(void *self) 968a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten{ 969a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten} 9708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten// OpenMAX AL Engine 9738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice, 9768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 9778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 9788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 9798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 9808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 981bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten //IXAEngine *thiz = (IXAEngine *) self; 9828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 9838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 9858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 9868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9888db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice, 9898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 9908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 9918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 9928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 9938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 994bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten //IXAEngine *thiz = (IXAEngine *) self; 9958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 9968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 9978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 9988db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 9998db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10008db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10018db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID, 10028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 10038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 10048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 10058db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 10068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 10078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 10088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (const SLboolean *) pInterfaceRequired); 10098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 10108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice, 10138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 10148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 10158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 10168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 10178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 10188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 10198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (const SLboolean *) pInterfaceRequired); 10208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 10218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer, 10248db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk, 10258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray, 10268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 10278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 10288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 10298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 10308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 10318b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (NULL == pPlayer) { 10328b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten result = XA_RESULT_PARAMETER_INVALID; 10338b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } else { 10348b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten *pPlayer = NULL; 10358b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten unsigned exposedMask; 10368b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER); 10378b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten assert(NULL != pCMediaPlayer_class); 10388b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten result = checkInterfaces(pCMediaPlayer_class, numInterfaces, 10398b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask); 10408b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS == result) { 10418b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 10428b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // Construct our new MediaPlayer instance 1043bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask, 10448b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf); 1045bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (NULL == thiz) { 10468b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten result = XA_RESULT_MEMORY_FAILURE; 10478b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } else { 10488b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 10498b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten do { 10508b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 10518b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // Initialize private fields not associated with an interface 10528b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 1053d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // Default data source in case of failure in checkDataSource 1054d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 1055d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1056d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1057d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // Default andio and image sink in case of failure in checkDataSink 1058d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL; 1059d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1060d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL; 1061d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1062d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1063d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // More default values, in case destructor needs to be called early 1064d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDirectLevel = 0; 1065d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 10668b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // (assume calloc or memset 0 during allocation) 10678b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // placement new 106813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#ifdef ANDROID 106913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // FIXME unnecessary once those fields are encapsulated in one class, rather 107013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi // than a structure 107168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>(); 107213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#endif 10738b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 10748b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // Check the source and sink parameters against generic constraints 10758b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 107694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc, 1077bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten &thiz->mDataSource, DATALOCATOR_MASK_URI 107894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef ANDROID 107994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten | DATALOCATOR_MASK_ANDROIDFD 1080eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE 108194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 108294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten , DATAFORMAT_MASK_MIME); 10838b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 10848b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 10858b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 10868b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 108794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc, 1088bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI | 108994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL); 10908b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 10918b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 10928b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 10938b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 109494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk, 1095bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL); 10968b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 10978b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 10988b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 10998b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 110094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk, 1101bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten &thiz->mImageVideoSink, DATALOCATOR_MASK_NATIVEDISPLAY, 110294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATAFORMAT_MASK_NULL); 11038b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 11048b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 11058b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 11068b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 1107bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink, 110894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE, 110994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATAFORMAT_MASK_NULL); 11108b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 11118b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 11128b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 11138b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 111494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray, 1115bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE, 111694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten DATAFORMAT_MASK_NULL); 11178b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 11188b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 11198b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 11208b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 11218b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // Unsafe to ever refer to application pointers again 11228b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pDataSrc = NULL; 11238b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pBankSrc = NULL; 11248b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pAudioSnk = NULL; 11258b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pImageVideoSnk = NULL; 11268b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pVibra = NULL; 11278b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten pLEDArray = NULL; 11288b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 11298b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // Check that the requested interfaces are compatible with the data source 1130d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // FIXME implement 11318b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 11328b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // check the source and sink parameters against platform support 11338b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#ifdef ANDROID 1134d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = android_Player_checkSourceSink(thiz); 11358b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 11368b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten break; 11378b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 11388b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#endif 11398b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 1140d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // AndroidBufferQueue-specific initialization 1141d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE == 1142d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDataSource.mLocator.mLocatorType) { 1143d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers; 1144d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1145d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // Avoid possible integer overflow during multiplication; this arbitrary 1146d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // maximum is big enough to not interfere with real applications, but 1147d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // small enough to not overflow. 1148d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (nbBuffers >= 256) { 1149d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 1150d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi break; 1151d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 115270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 115370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // initialize ABQ buffer type 115470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // assert below has been checked in android_audioPlayer_checkSourceSink 115570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType); 115670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (XA_CONTAINERTYPE_MPEG_TS == 115770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mDataSource.mFormat.mMIME.containerType) { 115870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts; 115970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { 116070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid; 116170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi SL_LOGE("Invalid buffer type in Android Buffer Queue"); 116270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 116370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 116470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 116570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // initialize ABQ memory 1166d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *) 1167d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader)); 1168d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (NULL == thiz->mAndroidBufferQueue.mBufferArray) { 1169d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi result = SL_RESULT_MEMORY_FAILURE; 1170d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi break; 1171d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } else { 1172d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi for (XAuint16 i=0 ; i<(nbBuffers + 1) ; i++) { 1173d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataBuffer = NULL; 1174d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataSize = 0; 1175d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mDataSizeConsumed = 0; 117670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi switch (thiz->mAndroidBufferQueue.mBufferType) { 117770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi case kAndroidBufferTypeMpeg2Ts: 117870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData. 117970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mTsCmdCode = ANDROID_MP2TSEVENT_NONE; 118070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray[i].mItems.mTsCmdData. 118170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mPts = 0; 118270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 118370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi default: 118470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi result = SL_RESULT_CONTENT_UNSUPPORTED; 118570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 118670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 1187d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 1188d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mFront = 1189d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray; 1190d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mRear = 1191d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mBufferArray; 1192d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 1193d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1194d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers; 1195d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1196d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 1197d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 1198d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // used to store the data source of our audio player 1199d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource; 1200d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 12018b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // platform-specific initialization 12028b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#ifdef ANDROID 1203bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_Player_create(thiz); 12048b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten#endif 12058b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 12068b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } while (0); 12078b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 12088b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten if (XA_RESULT_SUCCESS != result) { 1209bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Destroy(&thiz->mObject.mItf); 12108b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } else { 1211bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IObject_Publish(&thiz->mObject); 12128b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten // return the new media player object 1213bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten *pPlayer = (XAObjectItf) &thiz->mObject.mItf; 12148b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 12158b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 12168b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 12178b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 12188b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten 12198b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten } 12208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 12228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12248db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder, 12268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XADataSource *pAudioSrc, XADataSource *pImageVideoSrc, 12278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 12288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 12298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 12318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 1232bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten //IXAEngine *thiz = (IXAEngine *) self; 12338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 12348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 123594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#if 0 123694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pAudioSrc", pAudioSrc, 123794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pImageVideoSrc", pImageVideoSrc, 123894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten "pDataSink", pDataSnk, 123994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 124094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten 12418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 12428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix, 12468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 12478db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAboolean *pInterfaceRequired) 12488db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12498db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 12508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 12518db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 12528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (const SLboolean *) pInterfaceRequired); 12538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12568db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor, 12578db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XADataSource *pDataSource, XAuint32 numInterfaces, 12588db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired) 12598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 12618db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 12628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces, 12638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired); 12648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12658db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12668db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject, 12688db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten void *pParameters, XAuint32 objectID, XAuint32 numInterfaces, 12698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired) 12708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 12728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 12738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLObjectItf *) pObject, pParameters, objectID, numInterfaces, 12748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired); 12758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor, 12798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText) 12808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 12828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 1283bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten //IXAEngine *thiz = (IXAEngine *) self; 12848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 12858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 12878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 12888db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported) 12918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 12928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_ENTER_INTERFACE 12938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 12948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten if (NULL == pProfilesSupported) { 12958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = XA_RESULT_PARAMETER_INVALID; 12968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } else { 12978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#if 1 12988db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *pProfilesSupported = 0; 12999e0f457f2809f5f062ac052d4a304e8996b49a80Glenn Kasten // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL. 13008db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#else 13018db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // The generic implementation doesn't implement any of the profiles, they shouldn't be 13028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // declared as supported. Also exclude the fake profiles BASE and OPTIONAL. 13038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *pProfilesSupported = USE_PROFILES & 13048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE); 13058db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif 13068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten result = XA_RESULT_SUCCESS; 13078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten } 13088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XA_LEAVE_INTERFACE 13108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID, 13148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 *pNumSupportedInterfaces) 13158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 13178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_QueryNumSupportedInterfaces( 13188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, 13198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pNumSupportedInterfaces); 13208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID, 13248db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 index, XAInterfaceID *pInterfaceId) 13258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 13278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_QuerySupportedInterfaces( 13288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index, 13298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten (SLInterfaceID *) pInterfaceId); 13308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions) 13348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 13368db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_QueryNumSupportedExtensions( 13378db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions); 13388db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13408db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index, 13428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAchar *pExtensionName, XAint16 *pNameLength) 13438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 13458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 13468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten index, pExtensionName, (SLint16 *) pNameLength); 13478db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13488db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13498db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName, 13518db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAboolean *pSupported) 13528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES 13548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 13558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pExtensionName, pSupported); 13568db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13578db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13588db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex, 13608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor) 13618db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES EngineCapabilities 13638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return (XAresult) IEngineCapabilities_QueryLEDCapabilities( 13648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex, 13658db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pLEDDeviceID, (SLLEDDescriptor *) pDescriptor); 13668db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13688db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex, 13708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor) 13718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 13728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten // forward to OpenSL ES EngineCapabilities 13738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten return (XAresult) IEngineCapabilities_QueryVibraCapabilities( 13748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex, 13758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten pVibraDeviceID, (SLVibraDescriptor *) pDescriptor); 13768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 13778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten// OpenMAX AL engine v-table 13808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 13818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenstatic const struct XAEngineItf_ IXAEngine_Itf = { 13828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IEngine_CreateCameraDevice, 13838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IEngine_CreateRadioDevice, 13848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_CreateLEDDevice, 13858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_CreateVibraDevice, 13868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IEngine_CreateMediaPlayer, 13878db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IEngine_CreateMediaRecorder, 13888db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_CreateOutputMix, 13898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_CreateMetadataExtractor, 13908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_CreateExtensionObject, 13918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IEngine_GetImplementationInfo, 13928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QuerySupportedProfiles, 13938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QueryNumSupportedInterfaces, 13948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QuerySupportedInterfaces, 13958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QueryNumSupportedExtensions, 13968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QuerySupportedExtension, 13978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_IsExtensionSupported, 13988db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QueryLEDCapabilities, 13998db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten IXAEngine_QueryVibraCapabilities 14008db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten}; 14018db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 14028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten 14038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kastenvoid IXAEngine_init(void *self) 14048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{ 1405bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IXAEngine *thiz = (IXAEngine *) self; 1406bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mItf = &IXAEngine_Itf; 14078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten} 1408