IEngine.c revision a7b79e766ec6d95e9236168c27461c2ebaef4659
14b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/*
24b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Copyright (C) 2010 The Android Open Source Project
34b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines *
44b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
54b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * you may not use this file except in compliance with the License.
64b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * You may obtain a copy of the License at
74b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines *
84b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines *      http://www.apache.org/licenses/LICENSE-2.0
94b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines *
104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Unless required by applicable law or agreed to in writing, software
114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * See the License for the specific language governing permissions and
144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * limitations under the License.
154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines */
164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/* Engine implementation */
184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "sles_allinclusive.h"
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines{
254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    SL_ENTER_INTERFACE
264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#ifdef USE_OPTIONAL
284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    } else {
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        *pDevice = NULL;
324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines        unsigned exposedMask;
33f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            pInterfaceRequired, &exposedMask);
36f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        if (SL_RESULT_SUCCESS == result) {
371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            if (NULL == this) {
391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                result = SL_RESULT_MEMORY_FAILURE;
40f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            } else {
411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                this->mDeviceID = deviceID;
421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                IObject_Publish(&this->mObject);
431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                // return the new LED object
441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                *pDevice = &this->mObject.mItf;
451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            }
461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        }
471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    }
481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#else
491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#endif
511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    SL_LEAVE_INTERFACE
531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines}
541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines{
591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    SL_ENTER_INTERFACE
606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines
616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#ifdef USE_OPTIONAL
621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        result = SL_RESULT_PARAMETER_INVALID;
646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    } else {
656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        *pDevice = NULL;
661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        unsigned exposedMask;
67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        result = checkInterfaces(pCVibraDevice_class, numInterfaces,
691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        if (SL_RESULT_SUCCESS == result) {
711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            if (NULL == this) {
731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                result = SL_RESULT_MEMORY_FAILURE;
746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines            } else {
756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                this->mDeviceID = deviceID;
761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                IObject_Publish(&this->mObject);
771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                // return the new vibra object
781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                *pDevice = &this->mObject.mItf;
791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            }
801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        }
816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    }
821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#else
831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#endif
851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    SL_LEAVE_INTERFACE
871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines}
881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
894464d825c11349068f2917f9ebee86b721423f3cStephen Hines
904464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
914464d825c11349068f2917f9ebee86b721423f3cStephen Hines    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
924464d825c11349068f2917f9ebee86b721423f3cStephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
93d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines{
944464d825c11349068f2917f9ebee86b721423f3cStephen Hines    SL_ENTER_INTERFACE
951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    if (NULL == pPlayer) {
971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines       result = SL_RESULT_PARAMETER_INVALID;
98e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    } else {
994464d825c11349068f2917f9ebee86b721423f3cStephen Hines        *pPlayer = NULL;
1004464d825c11349068f2917f9ebee86b721423f3cStephen Hines        unsigned exposedMask;
1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
10303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
1041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines        if (SL_RESULT_SUCCESS == result) {
1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            // Construct our new AudioPlayer instance
107d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines            CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines            if (NULL == this) {
109d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines                result = SL_RESULT_MEMORY_FAILURE;
110d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines            } else {
1111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                do {
1134464d825c11349068f2917f9ebee86b721423f3cStephen Hines
11403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    // Initialize private fields not associated with an interface
1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    this->mMuteMask = 0;
1164464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    this->mSoloMask = 0;
1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    // const, will be set later by the containing AudioPlayer or MidiPlayer
1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    this->mNumChannels = 0;
119d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines                    this->mSampleRateMilliHz = 0;
1201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    // Check the source and sink parameters against generic constraints,
1224464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    // and make a local copy of all parameters in case other application threads
1234464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    // change memory concurrently.
1244464d825c11349068f2917f9ebee86b721423f3cStephen Hines
12503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    result = checkDataSource(pAudioSrc, &this->mDataSource);
12603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
12703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                        break;
1284464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    }
129d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines
1304464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    result = checkSourceFormatVsInterfacesCompatibility(&this->mDataSource,
1311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                            numInterfaces, pInterfaceIds, pInterfaceRequired);
1321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                        break;
13403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    }
135d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines
1361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    result = checkDataSink(pAudioSnk, &this->mDataSink, SL_OBJECTID_AUDIOPLAYER);
1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
138d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines                        break;
1391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    }
140d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines
1411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    // copy the buffer queue count from source locator to the buffer queue interface
1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    // we have already range-checked the value down to a smaller width
1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines                    this->mBufferQueue.mNumBuffers = (SL_DATALOCATOR_BUFFERQUEUE == *(SLuint32 *)
145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        pAudioSrc->pLocator) ? (SLuint16) ((SLDataLocator_BufferQueue *)
146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        pAudioSrc->pLocator)->numBuffers : 0;
147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    // check the audio source and sink parameters against platform support
1496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#ifdef ANDROID
150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    result = android_audioPlayer_checkSourceSink(this);
151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        break;
153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    }
154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines#endif
155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines#ifdef USE_SNDFILE
157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    result = SndFile_checkAudioPlayerSourceSink(this);
158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        break;
160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    }
161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines#endif
162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines#ifdef USE_OUTPUTMIXEXT
1646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    result = IOutputMixExt_checkAudioPlayerSourceSink(this);
165e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    if (SL_RESULT_SUCCESS != result) {
166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        break;
167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    }
168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines#endif
169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    // FIXME move to dedicated function
171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    // Allocate memory for buffer queue
172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                    //if (0 != this->mBufferQueue.mNumBuffers) {
174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        // inline allocation of circular mArray, up to a typical max
175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                        if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) {
176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
177c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        } else {
178c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            // Avoid possible integer overflow during multiplication; this arbitrary
179c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            // maximum is big enough to not interfere with real applications, but
180c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            // small enough to not overflow.
181c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            if (this->mBufferQueue.mNumBuffers >= 256) {
182c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                                result = SL_RESULT_MEMORY_FAILURE;
183c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                                break;
184c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            }
185c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            this->mBufferQueue.mArray = (BufferHeader *) malloc((this->mBufferQueue.
186c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                                mNumBuffers + 1) * sizeof(BufferHeader));
187c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            if (NULL == this->mBufferQueue.mArray) {
188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                                result = SL_RESULT_MEMORY_FAILURE;
189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                                break;
190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                            }
191c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        }
192c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        this->mBufferQueue.mFront = this->mBufferQueue.mArray;
193c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        this->mBufferQueue.mRear = this->mBufferQueue.mArray;
194c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        //}
195c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        // used to store the data source of our audio player
197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        this->mDynamicSource.mDataSource = &this->mDataSource.u.mSource;
198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        // platform-specific initialization
200c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#ifdef ANDROID
201c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                        android_audioPlayer_create(this);
202c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#endif
203c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
204c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines                } while (0);
205c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
206d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines                if (SL_RESULT_SUCCESS != result) {
2074464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    IObject_Destroy(&this->mObject.mItf);
2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines                } else {
2094464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    IObject_Publish(&this->mObject);
2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    // return the new audio player object
2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    *pPlayer = &this->mObject.mItf;
2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines                }
2134464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2144464d825c11349068f2917f9ebee86b721423f3cStephen Hines            }
2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines        }
216d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines
2174464d825c11349068f2917f9ebee86b721423f3cStephen Hines    }
2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines
219d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines    SL_LEAVE_INTERFACE
2204464d825c11349068f2917f9ebee86b721423f3cStephen Hines}
2214464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2224464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2234464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
2244464d825c11349068f2917f9ebee86b721423f3cStephen Hines    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
225d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2264464d825c11349068f2917f9ebee86b721423f3cStephen Hines{
227d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines    SL_ENTER_INTERFACE
2284464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2294464d825c11349068f2917f9ebee86b721423f3cStephen Hines#if defined(USE_OPTIONAL) || defined(ANDROID)
2304464d825c11349068f2917f9ebee86b721423f3cStephen Hines    if (NULL == pRecorder) {
2314464d825c11349068f2917f9ebee86b721423f3cStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
2324464d825c11349068f2917f9ebee86b721423f3cStephen Hines    } else {
2334464d825c11349068f2917f9ebee86b721423f3cStephen Hines        *pRecorder = NULL;
234d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines        unsigned exposedMask;
2354464d825c11349068f2917f9ebee86b721423f3cStephen Hines        const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
2364464d825c11349068f2917f9ebee86b721423f3cStephen Hines        result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines                pInterfaceIds, pInterfaceRequired, &exposedMask);
2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2394464d825c11349068f2917f9ebee86b721423f3cStephen Hines        if (SL_RESULT_SUCCESS == result) {
2404464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2414464d825c11349068f2917f9ebee86b721423f3cStephen Hines            // Construct our new AudioRecorder instance
2424464d825c11349068f2917f9ebee86b721423f3cStephen Hines            CAudioRecorder *this = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
2434464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    self);
2444464d825c11349068f2917f9ebee86b721423f3cStephen Hines            if (NULL == this) {
2454464d825c11349068f2917f9ebee86b721423f3cStephen Hines                result = SL_RESULT_MEMORY_FAILURE;
2464464d825c11349068f2917f9ebee86b721423f3cStephen Hines            } else {
2474464d825c11349068f2917f9ebee86b721423f3cStephen Hines
2484464d825c11349068f2917f9ebee86b721423f3cStephen Hines                do {
2494464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    // const, will be set later by the containing AudioRecorder
2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    this->mNumChannels = 0;
2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines                    this->mSampleRateMilliHz = 0;
252f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
253f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    // Check the source and sink parameters, and make a local copy of all parameters
254f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    result = checkDataSource(pAudioSrc, &this->mDataSource);
255f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    if (SL_RESULT_SUCCESS != result) {
256f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        break;
257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    }
258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    result = checkDataSink(pAudioSnk, &this->mDataSink, SL_OBJECTID_AUDIORECORDER);
259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    if (SL_RESULT_SUCCESS != result) {
260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        break;
261f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    }
262f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
263f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    // check the audio source and sink parameters against platform support
264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef ANDROID
265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    result = android_audioRecorder_checkSourceSinkSupport(this);
266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    if (SL_RESULT_SUCCESS != result) {
267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        break;
269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    }
270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
272f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef ANDROID
273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    // FIXME move to dedicated function
274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    SLuint32 locatorType = *(SLuint32 *) pAudioSnk->pLocator;
275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    if (locatorType == SL_DATALOCATOR_BUFFERQUEUE) {
276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        this->mBufferQueue.mNumBuffers = ((SLDataLocator_BufferQueue *)
277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                pAudioSnk->pLocator)->numBuffers;
278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        // inline allocation of circular Buffer Queue mArray, up to a typical max
279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) {
280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        } else {
282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            // Avoid possible integer overflow during multiplication; this arbitrary
283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            // maximum is big enough to not interfere with real applications, but
284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            // small enough to not overflow.
285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            if (this->mBufferQueue.mNumBuffers >= 256) {
286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                result = SL_RESULT_MEMORY_FAILURE;
287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                break;
288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            }
289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            this->mBufferQueue.mArray = (BufferHeader *) malloc((this->mBufferQueue.
290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                    mNumBuffers + 1) * sizeof(BufferHeader));
291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            if (NULL == this->mBufferQueue.mArray) {
292f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                result = SL_RESULT_MEMORY_FAILURE;
293f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                                break;
294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                            }
295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        }
296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        this->mBufferQueue.mFront = this->mBufferQueue.mArray;
297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                        this->mBufferQueue.mRear = this->mBufferQueue.mArray;
29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    }
299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
300f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    // platform-specific initialization
302f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef ANDROID
303f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    android_audioRecorder_create(this);
304f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
306f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                } while (0);
307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                if (SL_RESULT_SUCCESS != result) {
309f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    IObject_Destroy(&this->mObject.mItf);
310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                } else {
31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    IObject_Publish(&this->mObject);
31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    // return the new audio recorder object
31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    *pRecorder = &this->mObject.mItf;
31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                }
31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            }
31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
3179d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines        }
31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    }
320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#else
321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
322f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
323f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
324f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_LEAVE_INTERFACE
325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines}
326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
331f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
332f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
333f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
334f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
335f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#if defined(USE_GAME) || defined(USE_PHONE)
336f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
337f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
338f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        *pPlayer = NULL;
34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        unsigned exposedMask;
34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        if (SL_RESULT_SUCCESS == result) {
34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            if (NULL == this) {
34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                result = SL_RESULT_MEMORY_FAILURE;
34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            } else {
34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                // FIXME a fake value - why not use value from IPlay_init? what does CT check for?
35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                this->mPlay.mDuration = 0;
35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                IObject_Publish(&this->mObject);
35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                // return the new MIDI player object
35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                *pPlayer = &this->mObject.mItf;
35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            }
35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        }
35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    }
35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#else
35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#endif
36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_LEAVE_INTERFACE
36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines}
36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines{
36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_ENTER_INTERFACE
36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#ifdef USE_GAME
37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    if (NULL == pListener) {
37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = SL_RESULT_PARAMETER_INVALID;
37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    } else {
374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        *pListener = NULL;
37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        unsigned exposedMask;
37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
37703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = checkInterfaces(pCListener_class, numInterfaces,
37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        if (SL_RESULT_SUCCESS == result) {
38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            CListener *this = (CListener *) construct(pCListener_class, exposedMask, self);
38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            if (NULL == this) {
38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                result = SL_RESULT_MEMORY_FAILURE;
38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            } else {
38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                IObject_Publish(&this->mObject);
38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                // return the new 3D listener object
38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                *pListener = &this->mObject.mItf;
38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            }
38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        }
38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    }
39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#else
39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#endif
39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_LEAVE_INTERFACE
39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines}
39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines{
40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_ENTER_INTERFACE
40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#ifdef USE_GAME
40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    if (NULL == pGroup) {
40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = SL_RESULT_PARAMETER_INVALID;
40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    } else {
40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        *pGroup = NULL;
40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        unsigned exposedMask;
40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = checkInterfaces(pC3DGroup_class, numInterfaces,
41103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
41203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        if (SL_RESULT_SUCCESS == result) {
41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            C3DGroup *this = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            if (NULL == this) {
41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                result = SL_RESULT_MEMORY_FAILURE;
41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            } else {
41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                this->mMemberMask = 0;
41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                IObject_Publish(&this->mObject);
41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                // return the new 3D group object
42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                *pGroup = &this->mObject.mItf;
42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            }
42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        }
42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    }
42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#else
42503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#endif
42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_LEAVE_INTERFACE
42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines}
430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
43103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
43303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_ENTER_INTERFACE
43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    if (NULL == pMix) {
438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        *pMix = NULL;
441f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        unsigned exposedMask;
442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        result = checkInterfaces(pCOutputMix_class, numInterfaces,
444f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
445f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        if (SL_RESULT_SUCCESS == result) {
446f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
447f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            if (NULL == this) {
448f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                result = SL_RESULT_MEMORY_FAILURE;
449f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            } else {
450f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef ANDROID
451f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                android_outputMix_create(this);
452f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
453f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef USE_SDL
454f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                IEngine *thisEngine = this->mObject.mEngine;
455f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                interface_lock_exclusive(thisEngine);
456f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                bool unpause = false;
45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                if (NULL == thisEngine->mOutputMix) {
45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    thisEngine->mOutputMix = this;
45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    unpause = true;
46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                }
46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                interface_unlock_exclusive(thisEngine);
46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#endif
46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                IObject_Publish(&this->mObject);
46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#ifdef USE_SDL
46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                if (unpause) {
46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    // Enable SDL_callback to be called periodically by SDL's internal thread
46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                    SDL_PauseAudio(0);
46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                }
46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines#endif
4706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                // return the new output mix object
47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines                *pMix = &this->mObject.mItf;
47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines            }
47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines        }
47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    }
47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines
47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines    SL_LEAVE_INTERFACE
47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines}
4782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
479f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
480f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
481f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
482f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    const SLboolean *pInterfaceRequired)
4832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines{
484f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
485f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
486f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#if defined(USE_GAME) || defined(USE_MUSIC)
487f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if (NULL == pMetadataExtractor) {
488f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
489f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
490f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        *pMetadataExtractor = NULL;
491f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        unsigned exposedMask;
492f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        const ClassTable *pCMetadataExtractor_class =
493f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
494f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
495f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            pInterfaceIds, pInterfaceRequired, &exposedMask);
496f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        if (SL_RESULT_SUCCESS == result) {
497f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            CMetadataExtractor *this = (CMetadataExtractor *)
498f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                construct(pCMetadataExtractor_class, exposedMask, self);
499f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            if (NULL == this) {
500f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                result = SL_RESULT_MEMORY_FAILURE;
501f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            } else {
502f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                IObject_Publish(&this->mObject);
503f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                // return the new metadata extractor object
5042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines                *pMetadataExtractor = &this->mObject.mItf;
505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                result = SL_RESULT_SUCCESS;
506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            }
507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        }
508f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    }
509f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#else
510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    result = SL_RESULT_FEATURE_UNSUPPORTED;
511f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
512f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
513f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_LEAVE_INTERFACE
514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines}
515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
516f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
517f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
518f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
519f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
520f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
521f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
522f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
523f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if (NULL == pObject) {
524f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
525f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
526f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        *pObject = NULL;
527f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_FEATURE_UNSUPPORTED;
528f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    }
5292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
530f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_LEAVE_INTERFACE
531f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines}
532f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
5332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
5342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
5352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if (NULL == pNumSupportedInterfaces) {
540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        const ClassTable *class__ = objectIDtoClass(objectID);
543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        if (NULL == class__) {
544f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            result = SL_RESULT_FEATURE_UNSUPPORTED;
545f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        } else {
546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            SLuint32 count = 0;
547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            SLuint32 i;
548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            for (i = 0; i < class__->mInterfaceCount; ++i) {
549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                switch (class__->mInterfaces[i].mInterface) {
550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_IMPLICIT:
551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_EXPLICIT:
552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_DYNAMIC:
553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    ++count;
554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_UNAVAILABLE:
556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                default:
558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    assert(false);
559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                }
561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            }
562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            *pNumSupportedInterfaces = count;
563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            result = SL_RESULT_SUCCESS;
564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        }
565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    }
566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_LEAVE_INTERFACE;
568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines}
569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
573f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if (NULL == pInterfaceId) {
577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
578f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        *pInterfaceId = NULL;
580f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        const ClassTable *class__ = objectIDtoClass(objectID);
581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        if (NULL == class__) {
582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            result = SL_RESULT_FEATURE_UNSUPPORTED;
5832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines        } else {
584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            result = SL_RESULT_PARAMETER_INVALID; // will be reset later
585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            SLuint32 i;
586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            for (i = 0; i < class__->mInterfaceCount; ++i) {
587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                switch (class__->mInterfaces[i].mInterface) {
588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_IMPLICIT:
589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_EXPLICIT:
590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_DYNAMIC:
591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                case INTERFACE_UNAVAILABLE:
593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    continue;
594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                default:
595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    assert(false);
596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                }
598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                if (index == 0) {
599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH];
600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    result = SL_RESULT_SUCCESS;
601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                    break;
602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                }
603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines                --index;
604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines            }
605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        }
606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    }
607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_LEAVE_INTERFACE
609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines};
610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines{
614f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    SL_ENTER_INTERFACE
615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    if (NULL == pNumExtensions) {
617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_PARAMETER_INVALID;
618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    } else {
619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#ifdef ANDROID
620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        // FIXME support Android extensions
621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#else
622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        *pNumExtensions = 0;
623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#endif
624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines        result = SL_RESULT_SUCCESS;
625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    }
6262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
6272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    SL_LEAVE_INTERFACE
6282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines}
6292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
6302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
6312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
6322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
6336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines{
6346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    SL_ENTER_INTERFACE
635c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
636c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    // any index >= 0 will be >= number of supported extensions
637c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
638c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#ifdef ANDROID
639c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    // FIXME support Android extensions
640c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    result = SL_RESULT_PARAMETER_INVALID;
641c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#else
642c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    result = SL_RESULT_PARAMETER_INVALID;
643c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#endif
644c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
645c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    SL_LEAVE_INTERFACE
646c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines}
647c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
648c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
649c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesstatic SLresult IEngine_IsExtensionSupported(SLEngineItf self,
650c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    const SLchar *pExtensionName, SLboolean *pSupported)
651c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines{
652c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    SL_ENTER_INTERFACE
653c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
654c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    if (NULL == pExtensionName || NULL == pSupported) {
655c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines        result = SL_RESULT_PARAMETER_INVALID;
656c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    } else {
657c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#ifdef ANDROID
6582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines        // FIXME support Android extensions
659c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines        *pSupported = SL_BOOLEAN_FALSE;
660c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#else
661c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines        // no extensions are supported
6622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines        *pSupported = SL_BOOLEAN_FALSE;
663c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines#endif
664c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines        result = SL_RESULT_SUCCESS;
665c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    }
666c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
667c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    SL_LEAVE_INTERFACE
668c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines}
669c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
670c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
671c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesstatic const struct SLEngineItf_ IEngine_Itf = {
6722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateLEDDevice,
6732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateVibraDevice,
6742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateAudioPlayer,
6752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateAudioRecorder,
6762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateMidiPlayer,
6772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateListener,
6782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_Create3DGroup,
6792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateOutputMix,
6802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateMetadataExtractor,
6812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_CreateExtensionObject,
6822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_QueryNumSupportedInterfaces,
6832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_QuerySupportedInterfaces,
6842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_QueryNumSupportedExtensions,
6852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_QuerySupportedExtension,
6862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine_IsExtensionSupported
6872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines};
6882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines
6892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid IEngine_init(void *self)
6902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines{
6912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    IEngine *this = (IEngine *) self;
6922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mItf = &IEngine_Itf;
6932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    // mLossOfControlGlobal is initialized in CreateEngine
6942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines#ifdef USE_SDL
6952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mOutputMix = NULL;
6962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines#endif
6972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mInstanceCount = 1; // ourself
6982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mInstanceMask = 0;
6992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mChangedMask = 0;
7002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    unsigned i;
7012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    for (i = 0; i < MAX_INSTANCE; ++i) {
7022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines        this->mInstances[i] = NULL;
7032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    }
7042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mShutdown = SL_BOOLEAN_FALSE;
7052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mShutdownAck = SL_BOOLEAN_FALSE;
7062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines#if defined(ANDROID) && !defined(USE_BACKPORT)
7072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mEqNumPresets = 0;
7082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    this->mEqPresetNames = NULL;
7092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines#endif
7102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines}
7112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines