IEngine.c revision daf661248ff6ea2e21799e5114c78b7c1d49630e
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Engine implementation */ 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sles_allinclusive.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID) 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pDevice = NULL; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned exposedMask; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE); 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = checkInterfaces(pCLEDDevice_class, numInterfaces, 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pInterfaceIds, pInterfaceRequired, &exposedMask); 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_RESULT_SUCCESS != result) 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == this) 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_MEMORY_FAILURE; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLHSL *color = (SLHSL *) malloc(sizeof(SLHSL) * this->mLEDArray.mCount); 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(NULL != this->mLEDArray.mColor); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this->mLEDArray.mColor = color; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned i; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < this->mLEDArray.mCount; ++i) { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // per specification 1.0.1 pg. 259: "Default color is undefined." 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color->hue = 0; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color->saturation = 1000; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color->lightness = 1000; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this->mDeviceID = deviceID; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pDevice = &this->mObject.mItf; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_SUCCESS; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pDevice = NULL; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned exposedMask; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = checkInterfaces(pCVibraDevice_class, numInterfaces, 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pInterfaceIds, pInterfaceRequired, &exposedMask); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_RESULT_SUCCESS != result) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == this) 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_MEMORY_FAILURE; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this->mDeviceID = deviceID; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pDevice = &this->mObject.mItf; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_SUCCESS; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "entering IEngine_CreateAudioPlayer()\n"); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pPlayer) 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SL_RESULT_PARAMETER_INVALID; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pPlayer = NULL; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned exposedMask; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SLresult result = checkInterfaces(pCAudioPlayer_class, numInterfaces, 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pInterfaceIds, pInterfaceRequired, &exposedMask); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SL_RESULT_SUCCESS != result) 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check the source and sink parameters against generic constraints, 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and make a local copy of all parameters in case other application threads 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // change memory concurrently. 90 91 // DataSource checks 92 DataLocatorFormat myDataSource; 93 result = checkDataSource(pAudioSrc, &myDataSource); 94 if (SL_RESULT_SUCCESS != result) 95 return result; 96 97 // DataSink checks 98 DataLocatorFormat myDataSink; 99 result = checkDataSink(pAudioSnk, &myDataSink); 100 if (SL_RESULT_SUCCESS != result) { 101 freeDataLocatorFormat(&myDataSink); 102 return result; 103 } 104 105 // FIXME numerous leaks are possible from here on - check each return 106 // freeDataLocatorFormat(&myDataSource); 107 // freeDataLocatorFormat(&myDataSink); 108 109 fprintf(stderr, "\t after sles_checkSourceSink()\n"); 110 111 // check the audio source and sink parameters against platform support 112 113 SLDataSource myAudioSrc; 114 myAudioSrc.pLocator = &myDataSource.mLocator; 115 myAudioSrc.pFormat = &myDataSource.mFormat; 116 SLDataSink myAudioSnk; 117 myAudioSnk.pLocator = &myDataSink.mLocator; 118 myAudioSnk.pFormat = &myDataSink.mFormat; 119 120 SLuint32 numBuffers = 0; 121 122#ifdef USE_ANDROID 123 result = sles_to_android_checkAudioPlayerSourceSink(pAudioSrc, pAudioSnk); 124 if (SL_RESULT_SUCCESS != result) 125 return result; 126 fprintf(stderr, "\t after sles_to_android_checkAudioPlayerSourceSink()\n"); 127 numBuffers = 4; // FIXME 128#endif 129#ifdef USE_SNDFILE 130 SLchar *pathname; 131 result = SndFile_checkAudioPlayerSourceSink(pAudioSrc, pAudioSnk, &pathname, &numBuffers); 132 if (SL_RESULT_SUCCESS != result) 133 return result; 134#endif 135 136#ifdef USE_OUTPUTMIXEXT 137 struct Track *track, *track_; 138 result = IOutputMixExt_checkAudioPlayerSourceSink(pAudioSrc, pAudioSnk, &track_); 139 if (SL_RESULT_SUCCESS != result) 140 return result; 141 track = track_; 142#endif 143 144 // Construct our new AudioPlayer instance 145 CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self); 146 if (NULL == this) { 147 return SL_RESULT_MEMORY_FAILURE; 148 } 149 150 // Allocate memory for buffer queue 151 this->mBufferQueue.mNumBuffers = numBuffers; 152 if (0 != numBuffers) { 153 // inline allocation of circular mArray, up to a typical max 154 if (BUFFER_HEADER_TYPICAL >= numBuffers) { 155 this->mBufferQueue.mArray = this->mBufferQueue.mTypical; 156 } else { 157 // FIXME integer overflow possible during multiplication 158 this->mBufferQueue.mArray = (struct BufferHeader *) 159 malloc((numBuffers + 1) * sizeof(struct BufferHeader)); 160 if (NULL == this->mBufferQueue.mArray) { 161 free(this); 162 return SL_RESULT_MEMORY_FAILURE; 163 } 164 } 165 this->mBufferQueue.mFront = this->mBufferQueue.mArray; 166 this->mBufferQueue.mRear = this->mBufferQueue.mArray; 167 } 168 169 // used to store the data source of our audio player (FIXME - volatile) 170 this->mDynamicSource.mDataSource = pAudioSrc; 171 172 // platform-specific initialization 173 174#ifdef USE_SNDFILE 175 this->mSndFile.mPathname = pathname; 176 this->mSndFile.mIs0 = SL_BOOLEAN_TRUE; 177 this->mSndFile.mSNDFILE = NULL; 178 this->mSndFile.mRetryBuffer = NULL; 179 this->mSndFile.mRetrySize = 0; 180#endif 181 182#ifdef USE_OUTPUTMIXEXT 183 // link track to player 184 // const SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat; 185 // track->mDfPcm = df_pcm; 186 track->mBufferQueue = &this->mBufferQueue; 187 track->mPlay = &this->mPlay; 188 // next 2 fields must be initialized explicitly (not part of this) 189 track->mReader = NULL; 190 track->mAvail = 0; 191#endif 192 193#ifdef USE_ANDROID 194 sles_to_android_audioPlayerCreate(pAudioSrc, pAudioSnk, this); 195#endif 196 197 // return the new audio player object 198 *pPlayer = &this->mObject.mItf; 199 return SL_RESULT_SUCCESS; 200} 201 202static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, 203 SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, 204 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 205 const SLboolean *pInterfaceRequired) 206{ 207 if (NULL == pRecorder) 208 return SL_RESULT_PARAMETER_INVALID; 209 *pRecorder = NULL; 210 unsigned exposedMask; 211 const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER); 212 SLresult result = checkInterfaces(pCAudioRecorder_class, numInterfaces, 213 pInterfaceIds, pInterfaceRequired, &exposedMask); 214 if (SL_RESULT_SUCCESS != result) 215 return result; 216 return SL_RESULT_SUCCESS; 217} 218 219static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 220 SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 221 SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 222 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 223{ 224 if (NULL == pPlayer) 225 return SL_RESULT_PARAMETER_INVALID; 226 *pPlayer = NULL; 227 unsigned exposedMask; 228 const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER); 229 SLresult result = checkInterfaces(pCMidiPlayer_class, numInterfaces, 230 pInterfaceIds, pInterfaceRequired, &exposedMask); 231 if (SL_RESULT_SUCCESS != result) 232 return result; 233 if (NULL == pMIDISrc || NULL == pAudioOutput) 234 return SL_RESULT_PARAMETER_INVALID; 235 CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self); 236 if (NULL == this) 237 return SL_RESULT_MEMORY_FAILURE; 238 // return the new MIDI player object 239 *pPlayer = &this->mObject.mItf; 240 return SL_RESULT_SUCCESS; 241} 242 243static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 244 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 245 const SLboolean *pInterfaceRequired) 246{ 247 if (NULL == pListener) 248 return SL_RESULT_PARAMETER_INVALID; 249 *pListener = NULL; 250 unsigned exposedMask; 251 const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER); 252 SLresult result = checkInterfaces(pCListener_class, numInterfaces, 253 pInterfaceIds, pInterfaceRequired, &exposedMask); 254 if (SL_RESULT_SUCCESS != result) 255 return result; 256 return SL_RESULT_FEATURE_UNSUPPORTED; 257} 258 259static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, 260 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 261 const SLboolean *pInterfaceRequired) 262{ 263 if (NULL == pGroup) 264 return SL_RESULT_PARAMETER_INVALID; 265 *pGroup = NULL; 266 unsigned exposedMask; 267 const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP); 268 SLresult result = checkInterfaces(pC3DGroup_class, numInterfaces, 269 pInterfaceIds, pInterfaceRequired, &exposedMask); 270 if (SL_RESULT_SUCCESS != result) 271 return result; 272 return SL_RESULT_FEATURE_UNSUPPORTED; 273} 274 275static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, 276 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 277 const SLboolean *pInterfaceRequired) 278{ 279 if (NULL == pMix) 280 return SL_RESULT_PARAMETER_INVALID; 281 *pMix = NULL; 282 unsigned exposedMask; 283 const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX); 284 SLresult result = checkInterfaces(pCOutputMix_class, numInterfaces, 285 pInterfaceIds, pInterfaceRequired, &exposedMask); 286 if (SL_RESULT_SUCCESS != result) 287 return result; 288 COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self); 289 if (NULL == this) 290 return SL_RESULT_MEMORY_FAILURE; 291 *pMix = &this->mObject.mItf; 292 return SL_RESULT_SUCCESS; 293} 294 295static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, 296 SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource, 297 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 298 const SLboolean *pInterfaceRequired) 299{ 300 if (NULL == pMetadataExtractor) 301 return SL_RESULT_PARAMETER_INVALID; 302 *pMetadataExtractor = NULL; 303 unsigned exposedMask; 304 const ClassTable *pCMetadataExtractor_class = objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR); 305 SLresult result = checkInterfaces(pCMetadataExtractor_class, numInterfaces, 306 pInterfaceIds, pInterfaceRequired, &exposedMask); 307 if (SL_RESULT_SUCCESS != result) 308 return result; 309 CMetadataExtractor *this = (CMetadataExtractor *) 310 construct(pCMetadataExtractor_class, exposedMask, self); 311 if (NULL == this) 312 return SL_RESULT_MEMORY_FAILURE; 313 *pMetadataExtractor = &this->mObject.mItf; 314 return SL_RESULT_SUCCESS; 315} 316 317static SLresult IEngine_CreateExtensionObject(SLEngineItf self, 318 SLObjectItf *pObject, void *pParameters, SLuint32 objectID, 319 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 320 const SLboolean *pInterfaceRequired) 321{ 322 if (NULL == pObject) 323 return SL_RESULT_PARAMETER_INVALID; 324 *pObject = NULL; 325 return SL_RESULT_FEATURE_UNSUPPORTED; 326} 327 328static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 329 SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 330{ 331 if (NULL == pNumSupportedInterfaces) 332 return SL_RESULT_PARAMETER_INVALID; 333 const ClassTable *class__ = objectIDtoClass(objectID); 334 if (NULL == class__) 335 return SL_RESULT_FEATURE_UNSUPPORTED; 336 *pNumSupportedInterfaces = class__->mInterfaceCount; 337 return SL_RESULT_SUCCESS; 338} 339 340static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 341 SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 342{ 343 if (NULL == pInterfaceId) 344 return SL_RESULT_PARAMETER_INVALID; 345 const ClassTable *class__ = objectIDtoClass(objectID); 346 if (NULL == class__) 347 return SL_RESULT_FEATURE_UNSUPPORTED; 348 if (index >= class__->mInterfaceCount) 349 return SL_RESULT_PARAMETER_INVALID; 350 *pInterfaceId = &SL_IID_array[class__->mInterfaces[index].mMPH]; 351 return SL_RESULT_SUCCESS; 352}; 353 354static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, 355 SLuint32 *pNumExtensions) 356{ 357 if (NULL == pNumExtensions) 358 return SL_RESULT_PARAMETER_INVALID; 359 *pNumExtensions = 0; 360 return SL_RESULT_SUCCESS; 361} 362 363static SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 364 SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 365{ 366 // any index >= 0 will be >= number of supported extensions 367 return SL_RESULT_PARAMETER_INVALID; 368} 369 370static SLresult IEngine_IsExtensionSupported(SLEngineItf self, 371 const SLchar *pExtensionName, SLboolean *pSupported) 372{ 373 if (NULL == pExtensionName || NULL == pSupported) 374 return SL_RESULT_PARAMETER_INVALID; 375 *pSupported = SL_BOOLEAN_FALSE; 376 return SL_RESULT_SUCCESS; 377} 378 379static const struct SLEngineItf_ IEngine_Itf = { 380 IEngine_CreateLEDDevice, 381 IEngine_CreateVibraDevice, 382 IEngine_CreateAudioPlayer, 383 IEngine_CreateAudioRecorder, 384 IEngine_CreateMidiPlayer, 385 IEngine_CreateListener, 386 IEngine_Create3DGroup, 387 IEngine_CreateOutputMix, 388 IEngine_CreateMetadataExtractor, 389 IEngine_CreateExtensionObject, 390 IEngine_QueryNumSupportedInterfaces, 391 IEngine_QuerySupportedInterfaces, 392 IEngine_QueryNumSupportedExtensions, 393 IEngine_QuerySupportedExtension, 394 IEngine_IsExtensionSupported 395}; 396 397void IEngine_init(void *self) 398{ 399 IEngine *this = (IEngine *) self; 400 this->mItf = &IEngine_Itf; 401 // mLossOfControlGlobal is initialized in CreateEngine 402#ifndef NDEBUG 403 this->mInstanceCount = 0; 404 unsigned i; 405 for (i = 0; i < INSTANCE_MAX; ++i) 406 this->mInstances[i] = NULL; 407#endif 408} 409