IEngine.c revision acd88797a1d3b8225bab888d29036e245f275be5
19d10b341a0ba46f108cb96e46691197d778cbc06San Mehat/* 29d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Copyright (C) 2010 The Android Open Source Project 39d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * 49d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 59d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * you may not use this file except in compliance with the License. 69d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * You may obtain a copy of the License at 79d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * 89d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * http://www.apache.org/licenses/LICENSE-2.0 99d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * 109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Unless required by applicable law or agreed to in writing, software 119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * See the License for the specific language governing permissions and 149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * limitations under the License. 159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat */ 169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat/* Engine implementation */ 189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "sles_allinclusive.h" 209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 219d10b341a0ba46f108cb96e46691197d778cbc06San Mehatstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat{ 249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID) 259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return SL_RESULT_PARAMETER_INVALID; 269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *pDevice = NULL; 279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat unsigned exposedMask; 289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE); 299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat SLresult result = checkInterfaces(pCLEDDevice_class, numInterfaces, 309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat pInterfaceIds, pInterfaceRequired, &exposedMask); 319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (SL_RESULT_SUCCESS != result) 329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return result; 339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self); 349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (NULL == this) 359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return SL_RESULT_MEMORY_FAILURE; 369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat SLHSL *color = (SLHSL *) malloc(sizeof(SLHSL) * this->mLEDArray.mCount); 379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat assert(NULL != this->mLEDArray.mColor); 389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat this->mLEDArray.mColor = color; 399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat unsigned i; 403208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt for (i = 0; i < this->mLEDArray.mCount; ++i) { 413208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt // per specification 1.0.1 pg. 259: "Default color is undefined." 429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat color->hue = 0; 439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat color->saturation = 1000; 449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat color->lightness = 1000; 459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat this->mDeviceID = deviceID; 479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *pDevice = &this->mObject.mItf; 489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return SL_RESULT_SUCCESS; 499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat} 509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 519d10b341a0ba46f108cb96e46691197d778cbc06San Mehatstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat{ 54 if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID) 55 return SL_RESULT_PARAMETER_INVALID; 56 *pDevice = NULL; 57 unsigned exposedMask; 58 const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE); 59 SLresult result = checkInterfaces(pCVibraDevice_class, numInterfaces, 60 pInterfaceIds, pInterfaceRequired, &exposedMask); 61 if (SL_RESULT_SUCCESS != result) 62 return result; 63 CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self); 64 if (NULL == this) 65 return SL_RESULT_MEMORY_FAILURE; 66 this->mDeviceID = deviceID; 67 *pDevice = &this->mObject.mItf; 68 return SL_RESULT_SUCCESS; 69} 70 71static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 72 SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 73 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 74{ 75 fprintf(stderr, "entering IEngine_CreateAudioPlayer()\n"); 76 77 if (NULL == pPlayer) 78 return SL_RESULT_PARAMETER_INVALID; 79 *pPlayer = NULL; 80 unsigned exposedMask; 81 const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER); 82 SLresult result = checkInterfaces(pCAudioPlayer_class, numInterfaces, 83 pInterfaceIds, pInterfaceRequired, &exposedMask); 84 if (SL_RESULT_SUCCESS != result) 85 return result; 86 87 // Construct our new AudioPlayer instance 88 CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self); 89 if (NULL == this) { 90 return SL_RESULT_MEMORY_FAILURE; 91 } 92 93 // Check the source and sink parameters against generic constraints, 94 // and make a local copy of all parameters in case other application threads 95 // change memory concurrently. 96 97 result = checkDataSource(pAudioSrc, &this->mDataSource); 98 if (SL_RESULT_SUCCESS != result) 99 goto abort; 100 101 result = checkDataSink(pAudioSnk, &this->mDataSink); 102 if (SL_RESULT_SUCCESS != result) 103 goto abort; 104 105 fprintf(stderr, "\t after checkDataSource()/Sink()\n"); 106 107 // check the audio source and sink parameters against platform support 108 109#ifdef USE_ANDROID 110 result = sles_to_android_checkAudioPlayerSourceSink(this); 111 if (SL_RESULT_SUCCESS != result) 112 goto abort; 113 fprintf(stderr, "\t after sles_to_android_checkAudioPlayerSourceSink()\n"); 114#endif 115 116#ifdef USE_SNDFILE 117 result = SndFile_checkAudioPlayerSourceSink(this); 118 if (SL_RESULT_SUCCESS != result) 119 goto abort; 120#endif 121 122#ifdef USE_OUTPUTMIXEXT 123 result = IOutputMixExt_checkAudioPlayerSourceSink(this); 124 if (SL_RESULT_SUCCESS != result) 125 goto abort; 126#endif 127 128 // Allocate memory for buffer queue 129 //if (0 != this->mBufferQueue.mNumBuffers) { 130 // inline allocation of circular mArray, up to a typical max 131 if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) { 132 this->mBufferQueue.mArray = this->mBufferQueue.mTypical; 133 } else { 134 // FIXME integer overflow possible during multiplication 135 this->mBufferQueue.mArray = (struct BufferHeader *) 136 malloc((this->mBufferQueue.mNumBuffers + 1) * sizeof(struct BufferHeader)); 137 if (NULL == this->mBufferQueue.mArray) { 138 result = SL_RESULT_MEMORY_FAILURE; 139 goto abort; 140 } 141 } 142 this->mBufferQueue.mFront = this->mBufferQueue.mArray; 143 this->mBufferQueue.mRear = this->mBufferQueue.mArray; 144 //} 145 146 // used to store the data source of our audio player 147 this->mDynamicSource.mDataSource = &this->mDataSource.u.mSource; 148 149 // platform-specific initialization 150 151#ifdef USE_ANDROID 152 sles_to_android_audioPlayerCreate(this); 153#endif 154 155 // return the new audio player object 156 *pPlayer = &this->mObject.mItf; 157 return SL_RESULT_SUCCESS; 158 159abort: 160 freeDataLocatorFormat(&this->mDataSource); 161 freeDataLocatorFormat(&this->mDataSink); 162 if ((NULL != this->mBufferQueue.mArray) && 163 (this->mBufferQueue.mTypical != this->mBufferQueue.mArray)) { 164 free(this->mBufferQueue.mArray); 165 } 166 free(this); 167 return result; 168} 169 170static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, 171 SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, 172 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 173 const SLboolean *pInterfaceRequired) 174{ 175 if (NULL == pRecorder) 176 return SL_RESULT_PARAMETER_INVALID; 177 *pRecorder = NULL; 178 unsigned exposedMask; 179 const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER); 180 SLresult result = checkInterfaces(pCAudioRecorder_class, numInterfaces, 181 pInterfaceIds, pInterfaceRequired, &exposedMask); 182 if (SL_RESULT_SUCCESS != result) 183 return result; 184 185 // DataSource checks 186 DataLocatorFormat myDataSource; 187 result = checkDataSource(pAudioSrc, &myDataSource); 188 if (SL_RESULT_SUCCESS != result) 189 return result; 190 191 // DataSink checks 192 DataLocatorFormat myDataSink; 193 result = checkDataSink(pAudioSnk, &myDataSink); 194 if (SL_RESULT_SUCCESS != result) { 195 freeDataLocatorFormat(&myDataSink); 196 return result; 197 } 198 199 return SL_RESULT_SUCCESS; 200} 201 202static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 203 SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 204 SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 205 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 206{ 207 if (NULL == pPlayer) 208 return SL_RESULT_PARAMETER_INVALID; 209 *pPlayer = NULL; 210 unsigned exposedMask; 211 const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER); 212 SLresult result = checkInterfaces(pCMidiPlayer_class, numInterfaces, 213 pInterfaceIds, pInterfaceRequired, &exposedMask); 214 if (SL_RESULT_SUCCESS != result) 215 return result; 216 if (NULL == pMIDISrc || NULL == pAudioOutput) 217 return SL_RESULT_PARAMETER_INVALID; 218 CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self); 219 if (NULL == this) 220 return SL_RESULT_MEMORY_FAILURE; 221 // return the new MIDI player object 222 *pPlayer = &this->mObject.mItf; 223 return SL_RESULT_SUCCESS; 224} 225 226static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 227 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 228 const SLboolean *pInterfaceRequired) 229{ 230 if (NULL == pListener) 231 return SL_RESULT_PARAMETER_INVALID; 232 *pListener = NULL; 233 unsigned exposedMask; 234 const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER); 235 SLresult result = checkInterfaces(pCListener_class, numInterfaces, 236 pInterfaceIds, pInterfaceRequired, &exposedMask); 237 if (SL_RESULT_SUCCESS != result) 238 return result; 239 return SL_RESULT_FEATURE_UNSUPPORTED; 240} 241 242static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, 243 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 244 const SLboolean *pInterfaceRequired) 245{ 246 if (NULL == pGroup) 247 return SL_RESULT_PARAMETER_INVALID; 248 *pGroup = NULL; 249 unsigned exposedMask; 250 const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP); 251 SLresult result = checkInterfaces(pC3DGroup_class, numInterfaces, 252 pInterfaceIds, pInterfaceRequired, &exposedMask); 253 if (SL_RESULT_SUCCESS != result) 254 return result; 255 return SL_RESULT_FEATURE_UNSUPPORTED; 256} 257 258static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, 259 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 260 const SLboolean *pInterfaceRequired) 261{ 262 if (NULL == pMix) 263 return SL_RESULT_PARAMETER_INVALID; 264 *pMix = NULL; 265 unsigned exposedMask; 266 const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX); 267 SLresult result = checkInterfaces(pCOutputMix_class, numInterfaces, 268 pInterfaceIds, pInterfaceRequired, &exposedMask); 269 if (SL_RESULT_SUCCESS != result) 270 return result; 271 COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self); 272 if (NULL == this) 273 return SL_RESULT_MEMORY_FAILURE; 274 *pMix = &this->mObject.mItf; 275 return SL_RESULT_SUCCESS; 276} 277 278static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, 279 SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource, 280 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 281 const SLboolean *pInterfaceRequired) 282{ 283 if (NULL == pMetadataExtractor) 284 return SL_RESULT_PARAMETER_INVALID; 285 *pMetadataExtractor = NULL; 286 unsigned exposedMask; 287 const ClassTable *pCMetadataExtractor_class = objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR); 288 SLresult result = checkInterfaces(pCMetadataExtractor_class, numInterfaces, 289 pInterfaceIds, pInterfaceRequired, &exposedMask); 290 if (SL_RESULT_SUCCESS != result) 291 return result; 292 CMetadataExtractor *this = (CMetadataExtractor *) 293 construct(pCMetadataExtractor_class, exposedMask, self); 294 if (NULL == this) 295 return SL_RESULT_MEMORY_FAILURE; 296 *pMetadataExtractor = &this->mObject.mItf; 297 return SL_RESULT_SUCCESS; 298} 299 300static SLresult IEngine_CreateExtensionObject(SLEngineItf self, 301 SLObjectItf *pObject, void *pParameters, SLuint32 objectID, 302 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 303 const SLboolean *pInterfaceRequired) 304{ 305 if (NULL == pObject) 306 return SL_RESULT_PARAMETER_INVALID; 307 *pObject = NULL; 308 return SL_RESULT_FEATURE_UNSUPPORTED; 309} 310 311static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 312 SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 313{ 314 if (NULL == pNumSupportedInterfaces) 315 return SL_RESULT_PARAMETER_INVALID; 316 const ClassTable *class__ = objectIDtoClass(objectID); 317 if (NULL == class__) 318 return SL_RESULT_FEATURE_UNSUPPORTED; 319 *pNumSupportedInterfaces = class__->mInterfaceCount; 320 return SL_RESULT_SUCCESS; 321} 322 323static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 324 SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 325{ 326 if (NULL == pInterfaceId) 327 return SL_RESULT_PARAMETER_INVALID; 328 const ClassTable *class__ = objectIDtoClass(objectID); 329 if (NULL == class__) 330 return SL_RESULT_FEATURE_UNSUPPORTED; 331 if (index >= class__->mInterfaceCount) 332 return SL_RESULT_PARAMETER_INVALID; 333 *pInterfaceId = &SL_IID_array[class__->mInterfaces[index].mMPH]; 334 return SL_RESULT_SUCCESS; 335}; 336 337static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, 338 SLuint32 *pNumExtensions) 339{ 340 if (NULL == pNumExtensions) 341 return SL_RESULT_PARAMETER_INVALID; 342 *pNumExtensions = 0; 343 return SL_RESULT_SUCCESS; 344} 345 346static SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 347 SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 348{ 349 // any index >= 0 will be >= number of supported extensions 350 return SL_RESULT_PARAMETER_INVALID; 351} 352 353static SLresult IEngine_IsExtensionSupported(SLEngineItf self, 354 const SLchar *pExtensionName, SLboolean *pSupported) 355{ 356 if (NULL == pExtensionName || NULL == pSupported) 357 return SL_RESULT_PARAMETER_INVALID; 358 *pSupported = SL_BOOLEAN_FALSE; 359 return SL_RESULT_SUCCESS; 360} 361 362static const struct SLEngineItf_ IEngine_Itf = { 363 IEngine_CreateLEDDevice, 364 IEngine_CreateVibraDevice, 365 IEngine_CreateAudioPlayer, 366 IEngine_CreateAudioRecorder, 367 IEngine_CreateMidiPlayer, 368 IEngine_CreateListener, 369 IEngine_Create3DGroup, 370 IEngine_CreateOutputMix, 371 IEngine_CreateMetadataExtractor, 372 IEngine_CreateExtensionObject, 373 IEngine_QueryNumSupportedInterfaces, 374 IEngine_QuerySupportedInterfaces, 375 IEngine_QueryNumSupportedExtensions, 376 IEngine_QuerySupportedExtension, 377 IEngine_IsExtensionSupported 378}; 379 380void IEngine_init(void *self) 381{ 382 IEngine *this = (IEngine *) self; 383 this->mItf = &IEngine_Itf; 384 // mLossOfControlGlobal is initialized in CreateEngine 385 this->mInstanceCount = 0; 386 unsigned i; 387 for (i = 0; i < INSTANCE_MAX; ++i) 388 this->mInstances[i] = NULL; 389} 390