IEngine.c revision 7a79f519d89eb0e1a5b3f4005484b16d6854d7e2
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* Engine implementation */ 18 19#include "sles_allinclusive.h" 20 21 22static SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 23 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 24{ 25 SL_ENTER_INTERFACE 26 27#ifdef USE_CONFORMANCE 28 if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID) { 29 result = SL_RESULT_PARAMETER_INVALID; 30 } else { 31 *pDevice = NULL; 32 unsigned exposedMask; 33 const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE); 34 result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds, 35 pInterfaceRequired, &exposedMask); 36 if (SL_RESULT_SUCCESS == result) { 37 CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self); 38 if (NULL == this) { 39 result = SL_RESULT_MEMORY_FAILURE; 40 } else { 41 this->mDeviceID = deviceID; 42 *pDevice = &this->mObject.mItf; 43 } 44 } 45 } 46#else 47 result = SL_RESULT_FEATURE_UNSUPPORTED; 48#endif 49 50 SL_LEAVE_INTERFACE 51} 52 53 54static SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID, 55 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 56{ 57 SL_ENTER_INTERFACE 58 59#ifdef USE_CONFORMANCE 60 if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID) { 61 result = SL_RESULT_PARAMETER_INVALID; 62 } else { 63 *pDevice = NULL; 64 unsigned exposedMask; 65 const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE); 66 result = checkInterfaces(pCVibraDevice_class, numInterfaces, 67 pInterfaceIds, pInterfaceRequired, &exposedMask); 68 if (SL_RESULT_SUCCESS == result) { 69 CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self); 70 if (NULL == this) { 71 result = SL_RESULT_MEMORY_FAILURE; 72 } else { 73 this->mDeviceID = deviceID; 74 *pDevice = &this->mObject.mItf; 75 } 76 } 77 } 78#else 79 result = SL_RESULT_FEATURE_UNSUPPORTED; 80#endif 81 82 SL_LEAVE_INTERFACE 83} 84 85 86static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 87 SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 88 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 89{ 90 SL_ENTER_INTERFACE 91 92 if (NULL == pPlayer) { 93 result = SL_RESULT_PARAMETER_INVALID; 94 } else { 95 *pPlayer = NULL; 96 unsigned exposedMask; 97 const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER); 98 result = checkInterfaces(pCAudioPlayer_class, numInterfaces, 99 pInterfaceIds, pInterfaceRequired, &exposedMask); 100 if (SL_RESULT_SUCCESS == result) { 101 102 // Construct our new AudioPlayer instance 103 CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self); 104 if (NULL == this) { 105 result = SL_RESULT_MEMORY_FAILURE; 106 } else { 107 108 do { 109 110 // Initialize private fields not associated with an interface 111 this->mMuteMask = 0; 112 this->mSoloMask = 0; 113 // const, will be set later by the containing AudioPlayer or MidiPlayer 114 this->mNumChannels = 0; 115 this->mSampleRateMilliHz = 0; 116 117 // Check the source and sink parameters against generic constraints, 118 // and make a local copy of all parameters in case other application threads 119 // change memory concurrently. 120 121 result = checkDataSource(pAudioSrc, &this->mDataSource); 122 if (SL_RESULT_SUCCESS != result) { 123 break; 124 } 125 126 result = checkSourceFormatVsInterfacesCompatibility(&this->mDataSource, 127 numInterfaces, pInterfaceIds, pInterfaceRequired); 128 if (SL_RESULT_SUCCESS != result) { 129 break; 130 } 131 132 result = checkDataSink(pAudioSnk, &this->mDataSink); 133 if (SL_RESULT_SUCCESS != result) { 134 break; 135 } 136 137 // check the audio source and sink parameters against platform support 138#ifdef ANDROID 139 result = sles_to_android_checkAudioPlayerSourceSink(this); 140 if (SL_RESULT_SUCCESS != result) 141 break; 142#else 143 { 144 // because we init buffer queues in SndFile below, which is not always present 145 SLuint32 locatorType = *(SLuint32 *) pAudioSrc->pLocator; 146 if (locatorType == SL_DATALOCATOR_BUFFERQUEUE) 147 this->mBufferQueue.mNumBuffers = ((SLDataLocator_BufferQueue *) 148 pAudioSrc->pLocator)->numBuffers; 149 } 150#endif 151 152#ifdef USE_SNDFILE 153 result = SndFile_checkAudioPlayerSourceSink(this); 154 if (SL_RESULT_SUCCESS != result) 155 break; 156#endif 157 158#ifdef USE_OUTPUTMIXEXT 159 result = IOutputMixExt_checkAudioPlayerSourceSink(this); 160 if (SL_RESULT_SUCCESS != result) 161 break; 162#endif 163 164 // Allocate memory for buffer queue 165 //if (0 != this->mBufferQueue.mNumBuffers) { 166 // inline allocation of circular mArray, up to a typical max 167 if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) { 168 this->mBufferQueue.mArray = this->mBufferQueue.mTypical; 169 } else { 170 // Avoid possible integer overflow during multiplication; this arbitrary 171 // maximum is big enough to not interfere with real applications, but 172 // small enough to not overflow. 173 if (this->mBufferQueue.mNumBuffers >= 256) { 174 result = SL_RESULT_MEMORY_FAILURE; 175 break; 176 } 177 this->mBufferQueue.mArray = (BufferHeader *) malloc((this->mBufferQueue. 178 mNumBuffers + 1) * sizeof(BufferHeader)); 179 if (NULL == this->mBufferQueue.mArray) { 180 result = SL_RESULT_MEMORY_FAILURE; 181 break; 182 } 183 } 184 this->mBufferQueue.mFront = this->mBufferQueue.mArray; 185 this->mBufferQueue.mRear = this->mBufferQueue.mArray; 186 //} 187 188 // used to store the data source of our audio player 189 this->mDynamicSource.mDataSource = &this->mDataSource.u.mSource; 190 191 // platform-specific initialization 192#ifdef ANDROID 193 sles_to_android_audioPlayerCreate(this); 194#endif 195 196 // return the new audio player object 197 *pPlayer = &this->mObject.mItf; 198 199 } while (0); 200 201 if (SL_RESULT_SUCCESS != result) 202 (*this->mObject.mItf->Destroy)(&this->mObject.mItf); 203 204 } 205 } 206 207 } 208 209 SL_LEAVE_INTERFACE 210} 211 212 213static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder, 214 SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 215 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 216{ 217 SL_ENTER_INTERFACE 218 219#ifdef USE_CONFORMANCE 220 if (NULL == pRecorder) { 221 result = SL_RESULT_PARAMETER_INVALID; 222 } else { 223 *pRecorder = NULL; 224 unsigned exposedMask; 225 const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER); 226 result = checkInterfaces(pCAudioRecorder_class, numInterfaces, 227 pInterfaceIds, pInterfaceRequired, &exposedMask); 228 if (SL_RESULT_SUCCESS == result) { 229 230 // Construct our new AudioRecorder instance 231 CAudioRecorder *this = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask, 232 self); 233 if (NULL == this) { 234 result = SL_RESULT_MEMORY_FAILURE; 235 } else { 236 237 do { 238 239 // Check the source and sink parameters, and make a local copy of all parameters 240 result = checkDataSource(pAudioSrc, &this->mDataSource); 241 if (SL_RESULT_SUCCESS != result) 242 break; 243 result = checkDataSink(pAudioSnk, &this->mDataSink); 244 if (SL_RESULT_SUCCESS != result) 245 break; 246 247 // This section is not yet fully implemented 248 249 // return the new audio recorder object 250 *pRecorder = &this->mObject.mItf; 251 252 } while (0); 253 254 if (SL_RESULT_SUCCESS != result) 255 (*this->mObject.mItf->Destroy)(&this->mObject.mItf); 256 } 257 258 } 259 260 } 261#else 262 result = SL_RESULT_FEATURE_UNSUPPORTED; 263#endif 264 265 SL_LEAVE_INTERFACE 266} 267 268 269static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 270 SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 271 SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 272 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 273{ 274 SL_ENTER_INTERFACE 275 276#ifdef USE_CONFORMANCE 277 if (NULL == pPlayer || NULL == pMIDISrc || NULL == pAudioOutput) { 278 result = SL_RESULT_PARAMETER_INVALID; 279 } else { 280 *pPlayer = NULL; 281 unsigned exposedMask; 282 const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER); 283 result = checkInterfaces(pCMidiPlayer_class, numInterfaces, 284 pInterfaceIds, pInterfaceRequired, &exposedMask); 285 if (SL_RESULT_SUCCESS == result) { 286 CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self); 287 if (NULL == this) { 288 result = SL_RESULT_MEMORY_FAILURE; 289 } else { 290 // return the new MIDI player object 291 *pPlayer = &this->mObject.mItf; 292 } 293 } 294 } 295#else 296 result = SL_RESULT_FEATURE_UNSUPPORTED; 297#endif 298 299 SL_LEAVE_INTERFACE 300} 301 302 303static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 304 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 305{ 306 SL_ENTER_INTERFACE 307 308#ifdef USE_CONFORMANCE 309 if (NULL == pListener) { 310 result = SL_RESULT_PARAMETER_INVALID; 311 } else { 312 *pListener = NULL; 313 unsigned exposedMask; 314 const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER); 315 result = checkInterfaces(pCListener_class, numInterfaces, 316 pInterfaceIds, pInterfaceRequired, &exposedMask); 317 if (SL_RESULT_SUCCESS == result) { 318 CListener *this = (CListener *) construct(pCListener_class, exposedMask, self); 319 if (NULL == this) { 320 result = SL_RESULT_MEMORY_FAILURE; 321 } else { 322 // return the new listener object 323 *pListener = &this->mObject.mItf; 324 } 325 } 326 } 327#else 328 result = SL_RESULT_FEATURE_UNSUPPORTED; 329#endif 330 331 SL_LEAVE_INTERFACE 332} 333 334 335static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces, 336 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 337{ 338 SL_ENTER_INTERFACE 339 340#ifdef USE_CONFORMANCE 341 if (NULL == pGroup) { 342 result = SL_RESULT_PARAMETER_INVALID; 343 } else { 344 *pGroup = NULL; 345 unsigned exposedMask; 346 const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP); 347 result = checkInterfaces(pC3DGroup_class, numInterfaces, 348 pInterfaceIds, pInterfaceRequired, &exposedMask); 349 if (SL_RESULT_SUCCESS == result) { 350 C3DGroup *this = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self); 351 if (NULL == this) { 352 result = SL_RESULT_MEMORY_FAILURE; 353 } else { 354 this->mMemberMask = 0; 355 // return the new 3DGroup object 356 *pGroup = &this->mObject.mItf; 357 } 358 } 359 } 360#else 361 result = SL_RESULT_FEATURE_UNSUPPORTED; 362#endif 363 364 SL_LEAVE_INTERFACE 365} 366 367 368static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces, 369 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 370{ 371 SL_ENTER_INTERFACE 372 373 if (NULL == pMix) { 374 result = SL_RESULT_PARAMETER_INVALID; 375 } else { 376 *pMix = NULL; 377 unsigned exposedMask; 378 const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX); 379 result = checkInterfaces(pCOutputMix_class, numInterfaces, 380 pInterfaceIds, pInterfaceRequired, &exposedMask); 381 if (SL_RESULT_SUCCESS == result) { 382 COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self); 383 if (NULL == this) { 384 result = SL_RESULT_MEMORY_FAILURE; 385 } else { 386 *pMix = &this->mObject.mItf; 387 } 388 } 389 } 390 391 SL_LEAVE_INTERFACE 392} 393 394 395static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor, 396 SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 397 const SLboolean *pInterfaceRequired) 398{ 399 SL_ENTER_INTERFACE 400 401#ifdef USE_CONFORMANCE 402 if (NULL == pMetadataExtractor) { 403 result = SL_RESULT_PARAMETER_INVALID; 404 } else { 405 *pMetadataExtractor = NULL; 406 unsigned exposedMask; 407 const ClassTable *pCMetadataExtractor_class = 408 objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR); 409 result = checkInterfaces(pCMetadataExtractor_class, numInterfaces, 410 pInterfaceIds, pInterfaceRequired, &exposedMask); 411 if (SL_RESULT_SUCCESS == result) { 412 CMetadataExtractor *this = (CMetadataExtractor *) 413 construct(pCMetadataExtractor_class, exposedMask, self); 414 if (NULL == this) { 415 result = SL_RESULT_MEMORY_FAILURE; 416 } else { 417 *pMetadataExtractor = &this->mObject.mItf; 418 result = SL_RESULT_SUCCESS; 419 } 420 } 421 } 422#else 423 result = SL_RESULT_FEATURE_UNSUPPORTED; 424#endif 425 426 SL_LEAVE_INTERFACE 427} 428 429 430static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject, 431 void *pParameters, SLuint32 objectID, SLuint32 numInterfaces, 432 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 433{ 434 SL_ENTER_INTERFACE 435 436 if (NULL == pObject) { 437 result = SL_RESULT_PARAMETER_INVALID; 438 } else { 439 *pObject = NULL; 440 result = SL_RESULT_FEATURE_UNSUPPORTED; 441 } 442 443 SL_LEAVE_INTERFACE 444} 445 446 447static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 448 SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 449{ 450 SL_ENTER_INTERFACE 451 452 if (NULL == pNumSupportedInterfaces) { 453 result = SL_RESULT_PARAMETER_INVALID; 454 } else { 455 const ClassTable *class__ = objectIDtoClass(objectID); 456 if (NULL == class__) { 457 result = SL_RESULT_FEATURE_UNSUPPORTED; 458 } else { 459 SLuint32 count = 0; 460 SLuint32 i; 461 for (i = 0; i < class__->mInterfaceCount; ++i) 462 if (class__->mInterfaces[i].mInterface != INTERFACE_UNAVAILABLE) 463 ++count; 464 *pNumSupportedInterfaces = count; 465 result = SL_RESULT_SUCCESS; 466 } 467 } 468 469 SL_LEAVE_INTERFACE; 470} 471 472 473static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 474 SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 475{ 476 SL_ENTER_INTERFACE 477 478 if (NULL == pInterfaceId) { 479 result = SL_RESULT_PARAMETER_INVALID; 480 } else { 481 *pInterfaceId = NULL; 482 const ClassTable *class__ = objectIDtoClass(objectID); 483 if (NULL == class__) { 484 result = SL_RESULT_FEATURE_UNSUPPORTED; 485 } else { 486 result = SL_RESULT_PARAMETER_INVALID; // will be reset later 487 SLuint32 i; 488 for (i = 0; i < class__->mInterfaceCount; ++i) { 489 if (INTERFACE_UNAVAILABLE == class__->mInterfaces[i].mInterface) 490 continue; 491 if (index == 0) { 492 *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH]; 493 result = SL_RESULT_SUCCESS; 494 break; 495 } 496 --index; 497 } 498 } 499 } 500 501 SL_LEAVE_INTERFACE 502}; 503 504 505static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions) 506{ 507 SL_ENTER_INTERFACE 508 509 if (NULL == pNumExtensions) { 510 result = SL_RESULT_PARAMETER_INVALID; 511 } else { 512 *pNumExtensions = 0; 513 result = SL_RESULT_SUCCESS; 514 } 515 516 SL_LEAVE_INTERFACE 517} 518 519 520static SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 521 SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 522{ 523 SL_ENTER_INTERFACE 524 525 // any index >= 0 will be >= number of supported extensions 526 result = SL_RESULT_PARAMETER_INVALID; 527 528 SL_LEAVE_INTERFACE 529} 530 531 532static SLresult IEngine_IsExtensionSupported(SLEngineItf self, 533 const SLchar *pExtensionName, SLboolean *pSupported) 534{ 535 SL_ENTER_INTERFACE 536 537 if (NULL == pExtensionName || NULL == pSupported) { 538 result = SL_RESULT_PARAMETER_INVALID; 539 } else { 540 // no extensions are supported 541 *pSupported = SL_BOOLEAN_FALSE; 542 result = SL_RESULT_SUCCESS; 543 } 544 545 SL_LEAVE_INTERFACE 546} 547 548 549static const struct SLEngineItf_ IEngine_Itf = { 550 IEngine_CreateLEDDevice, 551 IEngine_CreateVibraDevice, 552 IEngine_CreateAudioPlayer, 553 IEngine_CreateAudioRecorder, 554 IEngine_CreateMidiPlayer, 555 IEngine_CreateListener, 556 IEngine_Create3DGroup, 557 IEngine_CreateOutputMix, 558 IEngine_CreateMetadataExtractor, 559 IEngine_CreateExtensionObject, 560 IEngine_QueryNumSupportedInterfaces, 561 IEngine_QuerySupportedInterfaces, 562 IEngine_QueryNumSupportedExtensions, 563 IEngine_QuerySupportedExtension, 564 IEngine_IsExtensionSupported 565}; 566 567void IEngine_init(void *self) 568{ 569 IEngine *this = (IEngine *) self; 570 this->mItf = &IEngine_Itf; 571 // mLossOfControlGlobal is initialized in CreateEngine 572#ifdef USE_SDL 573 this->mOutputMix = NULL; 574#endif 575 this->mInstanceCount = 1; // ourself 576 this->mInstanceMask = 0; 577 this->mChangedMask = 0; 578 unsigned i; 579 for (i = 0; i < MAX_INSTANCE; ++i) 580 this->mInstances[i] = NULL; 581 this->mShutdown = SL_BOOLEAN_FALSE; 582 int ok; 583 ok = pthread_cond_init(&this->mShutdownCond, (const pthread_condattr_t *) NULL); 584 assert(0 == ok); 585} 586