sles.cpp revision bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3
1/* Copyright 2010 The Android Open Source Project */ 2 3/* OpenSL ES prototype */ 4 5#include "OpenSLES.h" 6#include <stddef.h> // offsetof 7#include <stdlib.h> // malloc 8#include <string.h> // memcmp 9#include <stdio.h> // debugging 10#include <assert.h> // debugging 11 12#include "MPH.h" 13#include "MPH_to.h" 14 15#ifdef USE_SNDFILE 16#include <sndfile.h> 17#endif // USE_SNDFILE 18 19#ifdef USE_SDL 20#include <SDL/SDL_audio.h> 21#endif // USE_SDL 22 23#ifdef USE_OUTPUTMIXEXT 24#include "OutputMixExt.h" 25#endif 26 27/* Forward declarations */ 28 29extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX]; 30 31#ifdef __cplusplus 32#define this this_ 33#endif 34 35/* Private types */ 36 37// Hook functions 38 39typedef void (*VoidHook)(void *self); 40typedef SLresult (*StatusHook)(void *self); 41 42// Describes how an interface is related to a given class 43 44#define INTERFACE_IMPLICIT 0 45#define INTERFACE_EXPLICIT 1 46#define INTERFACE_OPTIONAL 2 47#define INTERFACE_DYNAMIC 3 48#define INTERFACE_DYNAMIC_GAME INTERFACE_DYNAMIC 49#define INTERFACE_DYNAMIC_MUSIC INTERFACE_DYNAMIC 50#define INTERFACE_DYNAMIC_MUSIC_GAME INTERFACE_DYNAMIC 51#define INTERFACE_EXPLICIT_GAME INTERFACE_EXPLICIT 52#define INTERFACE_GAME INTERFACE_OPTIONAL 53#define INTERFACE_GAME_MUSIC INTERFACE_OPTIONAL 54#define INTERFACE_MUSIC_GAME INTERFACE_OPTIONAL 55#define INTERFACE_OPTIONAL_DYNAMIC INTERFACE_DYNAMIC 56#define INTERFACE_PHONE_GAME INTERFACE_OPTIONAL 57#define INTERFACE_TBD INTERFACE_IMPLICIT 58 59// Maps an interface ID to its offset within the class that exposes it 60 61struct iid_vtable { 62 unsigned char mMPH; 63 unsigned char mInterface; 64 /*size_t*/ unsigned short mOffset; 65}; 66 67// Per-class const data shared by all instances of the same class 68 69struct class_ { 70 // needed by all classes (class class, the superclass of all classes) 71 const struct iid_vtable *mInterfaces; 72 SLuint32 mInterfaceCount; 73 const signed char *mMPH_to_index; 74 // FIXME not yet used 75 //const char * const mName; 76 size_t mSize; 77 SLuint32 mObjectID; 78 // Non-const here and below should be moved to separate struct, 79 // as each engine is its own universe. 80 // FIXME not yet used, actually should be per engine, no? 81 // SLuint32 mInstanceCount; 82 // append per-class data here 83 StatusHook mRealize; 84 VoidHook mDestroy; 85}; 86 87// Track describes each input to OutputMixer 88// FIXME not for Android 89 90struct Track { 91 const SLDataFormat_PCM *mDfPcm; 92 struct BufferQueue_interface *mBufferQueue; 93 struct Play_interface *mPlay; // mixer examines this track if non-NULL 94 const void *mReader; // pointer to next frame in BufferHeader.mBuffer 95 SLuint32 mAvail; // number of available bytes 96}; 97 98// BufferHeader describes each element of a BufferQueue, other than the data 99 100struct BufferHeader { 101 const void *mBuffer; 102 SLuint32 mSize; 103}; 104 105#ifdef USE_OUTPUTMIXEXT 106 107// stereo is a frame consisting of a pair of 16-bit PCM samples 108 109typedef struct { 110 short left; 111 short right; 112} stereo; 113 114#endif 115 116#ifdef USE_SNDFILE 117 118struct SndFile { 119 // save URI also? 120 SLchar *mPathname; 121 SNDFILE *mSNDFILE; 122 // These are used when Enqueue returns SL_RESULT_BUFFER_INSUFFICIENT 123 const void *mRetryBuffer; 124 SLuint32 mRetrySize; 125 SLboolean mIs0; // which buffer to use next 126 // FIXME magic numbers 127 short mBuffer0[512]; 128 short mBuffer1[512]; 129}; 130 131#endif // USE_SNDFILE 132 133/* Device table (change this when you port!) */ 134 135#define DEVICE_ID_HEADSET 1 136 137static const SLAudioOutputDescriptor AudioOutputDescriptor_headset = { 138 (SLchar *) "headset", 139 SL_DEVCONNECTION_ATTACHED_WIRED, 140 SL_DEVSCOPE_USER, 141 SL_DEVLOCATION_HEADSET, 142 SL_BOOLEAN_FALSE, 143 SL_SAMPLINGRATE_44_1, 144 SL_SAMPLINGRATE_44_1, 145 SL_BOOLEAN_TRUE, 146 NULL, 147 0, 148 2 149}; 150 151#define DEVICE_ID_HANDSFREE 2 152 153static const SLAudioOutputDescriptor AudioOutputDescriptor_handsfree = { 154 (SLchar *) "handsfree", 155 SL_DEVCONNECTION_INTEGRATED, 156 SL_DEVSCOPE_ENVIRONMENT, 157 SL_DEVLOCATION_HANDSET, 158 SL_BOOLEAN_FALSE, 159 SL_SAMPLINGRATE_44_1, 160 SL_SAMPLINGRATE_44_1, 161 SL_BOOLEAN_TRUE, 162 NULL, 163 0, 164 2 165}; 166 167/* Interface structures */ 168 169struct _3DCommit_interface { 170 const struct SL3DCommitItf_ *mItf; 171 void *this; 172 SLboolean mDeferred; 173}; 174 175struct _3DDoppler_interface { 176 const struct SL3DDopplerItf_ *mItf; 177 void *this; 178 union Cartesian_Spherical1 { 179 SLVec3D mCartesian; 180 struct { 181 SLmillidegree mAzimuth; 182 SLmillidegree mElevation; 183 SLmillidegree mSpeed; 184 } mSpherical; 185 } mVelocity; 186 SLpermille mDopplerFactor; 187}; 188 189struct _3DGrouping_interface { 190 const struct SL3DGroupingItf_ *mItf; 191 void *this; 192 SLObjectItf mGroup; 193}; 194 195struct _3DLocation_interface { 196 const struct SL3DLocationItf_ *mItf; 197 void *this; 198 union Cartesian_Spherical2 { 199 SLVec3D mCartesian; 200 struct { 201 SLmillidegree mAzimuth; 202 SLmillidegree mElevation; 203 SLmillidegree mDistance; 204 } mSpherical; 205 } mLocation; 206 SLmillidegree mHeading; 207 SLmillidegree mPitch; 208 SLmillidegree mRoll; 209 SLVec3D mFront; 210 SLVec3D mAbove; 211 SLVec3D mUp; 212}; 213 214struct _3DMacroscopic_interface { 215 const struct SL3DMacroscopicItf_ *mItf; 216 void *this; 217}; 218 219struct _3DSource_interface { 220 const struct SL3DSourceItf_ *mItf; 221 void *this; 222}; 223 224struct AudioDecoderCapabilities_interface { 225 const struct SLAudioDecoderCapabilitiesItf_ *mItf; 226 void *this; 227}; 228 229struct AudioEncoder_interface { 230 const struct SLAudioEncoderItf_ *mItf; 231 void *this; 232 SLAudioEncoderSettings mSettings; 233}; 234 235struct AudioEncoderCapabilities_interface { 236 const struct SLAudioEncoderCapabilitiesItf_ *mItf; 237 void *this; 238}; 239 240struct AudioIODeviceCapabilities_interface { 241 const struct SLAudioIODeviceCapabilitiesItf_ *mItf; 242 void *this; 243}; 244 245struct BassBoost_interface { 246 const struct SLBassBoostItf_ *mItf; 247 void *this; 248 SLboolean mEnabled; 249 SLpermille mStrength; 250}; 251 252struct BufferQueue_interface { 253 const struct SLBufferQueueItf_ *mItf; 254 void *this; 255 volatile SLBufferQueueState mState; 256 slBufferQueueCallback mCallback; 257 void *mContext; 258 SLuint32 mNumBuffers; 259 struct BufferHeader *mArray; 260 struct BufferHeader *mFront, *mRear; 261 // saves a malloc in the typical case 262#define BUFFER_HEADER_TYPICAL 4 263 struct BufferHeader mTypical[BUFFER_HEADER_TYPICAL+1]; 264}; 265 266struct DeviceVolume_interface { 267 const struct SLDeviceVolumeItf_ *mItf; 268 void *this; 269 SLint32 mVolume; // FIXME should be per-device 270}; 271 272struct DynamicInterfaceManagement_interface { 273 const struct SLDynamicInterfaceManagementItf_ *mItf; 274 void *this; 275 unsigned mAddedMask; // added interfaces, a subset of exposed interfaces 276 slDynamicInterfaceManagementCallback mCallback; 277 void *mContext; 278}; 279 280struct DynamicSource_interface { 281 const struct SLDynamicSourceItf_ *mItf; 282 void *this; 283}; 284 285struct EffectSend_interface { 286 const struct SLEffectSendItf_ *mItf; 287 void *this; 288}; 289 290struct Engine_interface { 291 const struct SLEngineItf_ *mItf; 292 void *this; 293 // FIXME Per-class non-const data such as vector of created objects 294}; 295 296struct EngineCapabilities_interface { 297 const struct SLEngineCapabilitiesItf_ *mItf; 298 void *this; 299}; 300 301struct EnvironmentalReverb_interface { 302 const struct SLEnvironmentalReverbItf_ *mItf; 303 void *this; 304}; 305 306struct Equalizer_interface { 307 const struct SLEqualizerItf_ *mItf; 308 void *this; 309}; 310 311struct LEDArray_interface { 312 const struct SLLEDArrayItf_ *mItf; 313 void *this; 314}; 315 316struct MetaDataExtraction_interface { 317 const struct SLMetaDataExractionItf_ *mItf; 318 void *this; 319}; 320 321struct MetaDataTraversal_interface { 322 const struct SLMetaDataTraversalItf_ *mItf; 323 void *this; 324}; 325 326struct MIDIMessage_interface { 327 const struct SLMIDIMessageItf_ *mItf; 328 void *this; 329}; 330 331struct MIDIMuteSolo_interface { 332 const struct SLMIDIMuteSoloItf_ *mItf; 333 void *this; 334}; 335 336struct MIDITempo_interface { 337 const struct SLMIDITempoItf_ *mItf; 338 void *this; 339}; 340 341struct MIDITime_interface { 342 const struct SLMIDITimeItf_ *mItf; 343 void *this; 344}; 345 346struct MuteSolo_interface { 347 const struct SLMuteSoloItf_ *mItf; 348 void *this; 349}; 350 351struct Object_interface { 352 const struct SLObjectItf_ *mItf; 353 // probably not needed for an Object, as it is always first 354 void *this; 355 const struct class_ *mClass; 356 volatile SLuint32 mState; 357 slObjectCallback mCallback; 358 void *mContext; 359 unsigned mExposedMask; // exposed interfaces 360 SLint32 mPriority; 361 SLboolean mPreemptable; 362 // FIXME a thread lock would go here 363 // FIXME also an object ID for RPC 364 // FIXME and a human-readable name for debugging 365}; 366 367struct OutputMix_interface { 368 const struct SLOutputMixItf_ *mItf; 369 void *this; 370 unsigned mActiveMask; // 1 bit per active track 371 struct Track mTracks[32]; 372}; 373 374#ifdef USE_OUTPUTMIXEXT 375struct OutputMixExt_interface { 376 const struct SLOutputMixExtItf_ *mItf; 377 void *this; 378}; 379#endif 380 381struct Pitch_interface { 382 const struct SLPitchItf_ *mItf; 383 void *this; 384}; 385 386struct Play_interface { 387 const struct SLPlayItf_ *mItf; 388 void *this; 389 volatile SLuint32 mState; 390 SLmillisecond mDuration; 391 SLmillisecond mPosition; 392 // unsigned mPositionSamples; // position in sample units 393 slPlayCallback mCallback; 394 void *mContext; 395 SLuint32 mEventFlags; 396 SLmillisecond mMarkerPosition; 397 SLmillisecond mPositionUpdatePeriod; 398}; 399 400struct PlaybackRate_interface { 401 const struct SLPlaybackRateItf_ *mItf; 402 void *this; 403}; 404 405struct PrefetchStatus_interface { 406 const struct SLPrefetchStatusItf_ *mItf; 407 void *this; 408}; 409 410struct PresetReverb_interface { 411 const struct SLPresetReverbItf_ *mItf; 412 void *this; 413 SLuint16 mPreset; 414}; 415 416struct RatePitch_interface { 417 const struct SLRatePitchItf_ *mItf; 418 void *this; 419}; 420 421struct Record_interface { 422 const struct SLRecordItf_ *mItf; 423 void *this; 424}; 425 426struct Seek_interface { 427 const struct SLSeekItf_ *mItf; 428 void *this; 429 SLmillisecond mPos; 430 SLboolean mLoopEnabled; 431 SLmillisecond mStartPos; 432 SLmillisecond mEndPos; 433}; 434 435struct ThreadSync_interface { 436 const struct SLThreadSyncItf_ *mItf; 437 void *this; 438}; 439 440struct Vibra_interface { 441 const struct SLVibraItf_ *mItf; 442 void *this; 443}; 444 445struct Virtualizer_interface { 446 const struct SLVirtualizerItf_ *mItf; 447 void *this; 448 SLboolean mEnabled; 449 SLpermille mStrength; 450}; 451 452struct Visualization_interface { 453 const struct SLVisualizationItf_ *mItf; 454 void *this; 455 slVisualizationCallback mCallback; 456 void *mContext; 457 SLmilliHertz mRate; 458}; 459 460struct Volume_interface { 461 const struct SLVolumeItf_ *mItf; 462 void *this; 463 SLmillibel mLevel; 464 SLboolean mMute; 465 SLboolean mEnableStereoPosition; 466 SLpermille mStereoPosition; 467}; 468 469/* Class structures */ 470 471struct _3DGroup_class { 472 struct Object_interface mObject; 473 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 474 struct _3DLocation_interface m3DLocation; 475 struct _3DDoppler_interface m3DDoppler; 476 struct _3DSource_interface m3DSource; 477 struct _3DMacroscopic_interface m3DMacroscopic; 478}; 479 480struct AudioPlayer_class { 481 struct Object_interface mObject; 482 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 483 struct Play_interface mPlay; 484 struct _3DDoppler_interface m3DDoppler; 485 struct _3DGrouping_interface m3DGrouping; 486 struct _3DLocation_interface m3DLocation; 487 struct _3DSource_interface m3DSource; 488 struct BufferQueue_interface mBufferQueue; 489 struct EffectSend_interface mEffectSend; 490 struct MuteSolo_interface mMuteSolo; 491 struct MetaDataExtraction_interface mMetaDataExtraction; 492 struct MetaDataTraversal_interface mMetaDataTraversal; 493 struct PrefetchStatus_interface mPrefetchStatus; 494 struct RatePitch_interface mRatePitch; 495 struct Seek_interface mSeek; 496 struct Volume_interface mVolume; 497 // optional interfaces 498 struct _3DMacroscopic_interface m3DMacroscopic; 499 struct BassBoost_interface mBassBoost; 500 struct DynamicSource_interface mDynamicSource; 501 struct EnvironmentalReverb_interface mEnvironmentalReverb; 502 struct Equalizer_interface mEqualizer; 503 struct Pitch_interface mPitch; 504 struct PresetReverb_interface mPresetReverb; 505 struct PlaybackRate_interface mPlaybackRate; 506 struct Virtualizer_interface mVirtualizer; 507 struct Visualization_interface mVisualization; 508 // rest of fields are not related to the interfaces 509#ifdef USE_SNDFILE 510 struct SndFile mSndFile; 511#endif // USE_SNDFILE 512 // FIXME union per kind of AudioPlayer: MediaPlayer, AudioTrack, etc. 513}; 514 515struct AudioRecorder_class { 516 // mandated interfaces 517 struct Object_interface mObject; 518 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 519 struct Record_interface mRecord; 520 struct AudioEncoder_interface mAudioEncoder; 521 // optional interfaces 522 struct BassBoost_interface mBassBoost; 523 struct DynamicSource_interface mDynamicSource; 524 struct Equalizer_interface mEqualizer; 525 struct Visualization_interface mVisualization; 526 struct Volume_interface mVolume; 527}; 528 529struct Engine_class { 530 // mandated implicit interfaces 531 struct Object_interface mObject; 532 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 533 struct Engine_interface mEngine; 534 struct EngineCapabilities_interface mEngineCapabilities; 535 struct ThreadSync_interface mThreadSync; 536 // mandated explicit interfaces 537 struct AudioIODeviceCapabilities_interface mAudioIODeviceCapabilities; 538 struct AudioDecoderCapabilities_interface mAudioDecoderCapabilities; 539 struct AudioEncoderCapabilities_interface mAudioEncoderCapabilities; 540 struct _3DCommit_interface m3DCommit; 541 // optional interfaces 542 struct DeviceVolume_interface mDeviceVolume; 543 // additional fields not associated with interfaces 544 SLboolean mThreadSafe; 545 SLboolean mLossOfControl; 546}; 547 548struct LEDDevice_class { 549 // mandated interfaces 550 struct Object_interface mObject; 551 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 552 struct LEDArray_interface mLED; 553 // 554 SLuint32 mDeviceID; 555}; 556 557struct Listener_class { 558 // mandated interfaces 559 struct Object_interface mObject; 560 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 561 struct _3DDoppler_interface m3DDoppler; 562 struct _3DLocation_interface m3DLocation; 563}; 564 565struct MetadataExtractor_class { 566 // mandated interfaces 567 struct Object_interface mObject; 568 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 569 struct DynamicSource_interface mDynamicSource; 570 struct MetaDataExtraction_interface mMetaDataExtraction; 571 struct MetaDataTraversal_interface mMetaDataTraversal; 572}; 573 574struct MidiPlayer_class { 575 // mandated interfaces 576 struct Object_interface mObject; 577 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 578 struct Play_interface mPlay; 579 struct _3DDoppler_interface m3DDoppler; 580 struct _3DGrouping_interface m3DGrouping; 581 struct _3DLocation_interface m3DLocation; 582 struct _3DSource_interface m3DSource; 583 struct BufferQueue_interface mBufferQueue; 584 struct EffectSend_interface mEffectSend; 585 struct MuteSolo_interface mMuteSolo; 586 struct MetaDataExtraction_interface mMetaDataExtraction; 587 struct MetaDataTraversal_interface mMetaDataTraversal; 588 struct MIDIMessage_interface mMIDIMessage; 589 struct MIDITime_interface mMIDITime; 590 struct MIDITempo_interface mMIDITempo; 591 struct MIDIMuteSolo_interface mMIDIMuteSolo; 592 struct PrefetchStatus_interface mPrefetchStatus; 593 struct Seek_interface mSeek; 594 struct Volume_interface mVolume; 595 // optional interfaces 596 struct _3DMacroscopic_interface m3DMacroscopic; 597 struct BassBoost_interface mBassBoost; 598 struct DynamicSource_interface mDynamicSource; 599 struct EnvironmentalReverb_interface mEnvironmentalReverb; 600 struct Equalizer_interface mEqualizer; 601 struct Pitch_interface mPitch; 602 struct PresetReverb_interface mPresetReverb; 603 struct PlaybackRate_interface mPlaybackRate; 604 struct Virtualizer_interface mVirtualizer; 605 struct Visualization_interface mVisualization; 606}; 607 608struct OutputMix_class { 609 // mandated interfaces 610 struct Object_interface mObject; 611 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 612 struct OutputMix_interface mOutputMix; 613#ifdef USE_OUTPUTMIXEXT 614 struct OutputMixExt_interface mOutputMixExt; 615#endif 616 struct EnvironmentalReverb_interface mEnvironmentalReverb; 617 struct Equalizer_interface mEqualizer; 618 struct PresetReverb_interface mPresetReverb; 619 struct Virtualizer_interface mVirtualizer; 620 struct Volume_interface mVolume; 621 // optional interfaces 622 struct BassBoost_interface mBassBoost; 623 struct Visualization_interface mVisualization; 624}; 625 626struct VibraDevice_class { 627 // mandated interfaces 628 struct Object_interface mObject; 629 struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement; 630 struct Vibra_interface mVibra; 631 // 632 SLuint32 mDeviceID; 633}; 634 635/* Private functions */ 636 637// Map SLInterfaceID to its minimal perfect hash (MPH), or -1 if unknown 638 639static int IID_to_MPH(const SLInterfaceID iid) 640{ 641 if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid) 642 return iid - &SL_IID_array[0]; 643 if (NULL != iid) { 644 // FIXME Replace this linear search by a good MPH algorithm 645 const struct SLInterfaceID_ *srch = &SL_IID_array[0]; 646 unsigned MPH; 647 for (MPH = 0; MPH < MPH_MAX; ++MPH, ++srch) 648 if (!memcmp(iid, srch, sizeof(struct SLInterfaceID_))) 649 return MPH; 650 } 651 return -1; 652} 653 654static SLresult checkInterfaces(const struct class_ *class__, 655 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 656 const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 657{ 658 assert(NULL != class__ && NULL != pExposedMask); 659 unsigned exposedMask = 0; 660 const struct iid_vtable *interfaces = class__->mInterfaces; 661 SLuint32 interfaceCount = class__->mInterfaceCount; 662 SLuint32 i; 663 // FIXME This section could be pre-computed per class 664 for (i = 0; i < interfaceCount; ++i) { 665 switch (interfaces[i].mInterface) { 666 case INTERFACE_IMPLICIT: 667 exposedMask |= 1 << i; 668 break; 669 default: 670 break; 671 } 672 } 673 if (0 < numInterfaces) { 674 if (NULL == pInterfaceIds || NULL == pInterfaceRequired) 675 return SL_RESULT_PARAMETER_INVALID; 676 for (i = 0; i < numInterfaces; ++i) { 677 SLInterfaceID iid = pInterfaceIds[i]; 678 if (NULL == iid) 679 return SL_RESULT_PARAMETER_INVALID; 680 int mph = IID_to_MPH(iid); 681 if (mph < 0) { 682 if (pInterfaceRequired[i]) 683 return SL_RESULT_FEATURE_UNSUPPORTED; 684 continue; 685 } 686 int interfaceIndex = class__->mMPH_to_index[mph]; 687 if (interfaceIndex < 0) { 688 if (pInterfaceRequired[i]) 689 return SL_RESULT_FEATURE_UNSUPPORTED; 690 continue; 691 } 692 if (exposedMask & (1 << interfaceIndex)) 693#if 0 // FIXME this seems a bit strong? what is correct logic? 694// we are requesting a duplicate explicit interface, 695// or we are requesting one which is already implicit ? 696 return SL_RESULT_PARAMETER_INVALID; 697#else 698 continue; 699#endif 700 exposedMask |= (1 << interfaceIndex); 701 } 702 } 703 *pExposedMask = exposedMask; 704 return SL_RESULT_SUCCESS; 705} 706 707/* Interface initialization hooks */ 708 709static void _3DCommit_init(void *self) 710{ 711 extern const struct SL3DCommitItf_ _3DCommit_3DCommitItf; 712 struct _3DCommit_interface *this = (struct _3DCommit_interface *) self; 713 this->mItf = &_3DCommit_3DCommitItf; 714#ifndef NDEBUG 715 this->mDeferred = SL_BOOLEAN_FALSE; 716#endif 717} 718 719static void _3DDoppler_init(void *self) 720{ 721 //struct _3DDoppler_interface *this = 722 // (struct _3DDoppler_interface *) self; 723} 724 725static void _3DGrouping_init(void *self) 726{ 727 //struct _3DGrouping_interface *this = 728 // (struct _3DGrouping_interface *) self; 729} 730 731static void _3DLocation_init(void *self) 732{ 733 //struct _3DLocation_interface *this = 734 // (struct _3DLocation_interface *) self; 735} 736 737static void _3DMacroscopic_init(void *self) 738{ 739 //struct _3DMacroscopic_interface *this = 740 // (struct _3DMacroscopic_interface *) self; 741} 742 743static void _3DSource_init(void *self) 744{ 745 //struct _3DSource_interface *this = 746 // (struct _3DSource_interface *) self; 747} 748 749static void AudioDecoderCapabilities_init(void *self) 750{ 751 extern const struct SLAudioDecoderCapabilitiesItf_ 752 AudioDecoderCapabilities_AudioDecoderCapabilitiesItf; 753 struct AudioDecoderCapabilities_interface *this = 754 (struct AudioDecoderCapabilities_interface *) self; 755 this->mItf = &AudioDecoderCapabilities_AudioDecoderCapabilitiesItf; 756} 757 758static void AudioEncoderCapabilities_init(void *self) 759{ 760 extern const struct SLAudioEncoderCapabilitiesItf_ 761 AudioEncoderCapabilities_AudioEncoderCapabilitiesItf; 762 struct AudioEncoderCapabilities_interface *this = 763 (struct AudioEncoderCapabilities_interface *) self; 764 this->mItf = &AudioEncoderCapabilities_AudioEncoderCapabilitiesItf; 765} 766 767static void AudioEncoder_init(void *self) 768{ 769 //struct AudioEncoder_interface *this = 770 // (struct AudioEncoder_interface *) self; 771} 772 773static void AudioIODeviceCapabilities_init(void *self) 774{ 775 extern const struct SLAudioIODeviceCapabilitiesItf_ 776 AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf; 777 struct AudioIODeviceCapabilities_interface *this = 778 (struct AudioIODeviceCapabilities_interface *) self; 779 this->mItf = &AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf; 780} 781 782static void BassBoost_init(void *self) 783{ 784 //struct BassBoost_interface *this = 785 // (struct BassBoost_interface *) self; 786} 787 788static void BufferQueue_init(void *self) 789{ 790 extern const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf; 791 struct BufferQueue_interface *this = (struct BufferQueue_interface *) self; 792 this->mItf = &BufferQueue_BufferQueueItf; 793#ifndef NDEBUG 794 this->mState.count = 0; 795 this->mState.playIndex = 0; 796 this->mCallback = NULL; 797 this->mContext = NULL; 798 this->mNumBuffers = 0; 799 this->mArray = NULL; 800 this->mFront = NULL; 801 this->mRear = NULL; 802#endif 803} 804 805static void DeviceVolume_init(void *self) 806{ 807 extern const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf; 808 struct DeviceVolume_interface *this = 809 (struct DeviceVolume_interface *) self; 810 this->mItf = &DeviceVolume_DeviceVolumeItf; 811} 812 813static void DynamicInterfaceManagement_init(void *self) 814{ 815 extern const struct SLDynamicInterfaceManagementItf_ 816 DynamicInterfaceManagement_DynamicInterfaceManagementItf; 817 struct DynamicInterfaceManagement_interface *this = 818 (struct DynamicInterfaceManagement_interface *) self; 819 this->mItf = 820 &DynamicInterfaceManagement_DynamicInterfaceManagementItf; 821#ifndef NDEBUG 822 this->mAddedMask = 0; 823 this->mCallback = NULL; 824 this->mContext = NULL; 825#endif 826} 827 828static void DynamicSource_init(void *self) 829{ 830 //struct DynamicSource_interface *this = 831 // (struct DynamicSource_interface *) self; 832} 833 834static void EffectSend_init(void *self) 835{ 836 //struct EffectSend_interface *this = 837 // (struct EffectSend_interface *) self; 838} 839 840static void Engine_init(void *self) 841{ 842 extern const struct SLEngineItf_ Engine_EngineItf; 843 struct Engine_interface *this = (struct Engine_interface *) self; 844 this->mItf = &Engine_EngineItf; 845} 846 847static void EngineCapabilities_init(void *self) 848{ 849 extern const struct SLEngineCapabilitiesItf_ 850 EngineCapabilities_EngineCapabilitiesItf; 851 struct EngineCapabilities_interface *this = 852 (struct EngineCapabilities_interface *) self; 853 this->mItf = &EngineCapabilities_EngineCapabilitiesItf; 854} 855 856static void EnvironmentalReverb_init(void *self) 857{ 858 //struct EnvironmentalReverb_interface *this = 859 //(struct EnvironmentalReverb_interface *) self; 860} 861 862static void Equalizer_init(void *self) 863{ 864 //struct Equalizer_interface *this = 865 // (struct Equalizer_interface *) self; 866} 867 868static void LEDArray_init(void *self) 869{ 870 extern const struct SLLEDArrayItf_ LEDArray_LEDArrayItf; 871 struct LEDArray_interface *this = (struct LEDArray_interface *) self; 872 this->mItf = &LEDArray_LEDArrayItf; 873} 874 875static void MetaDataExtraction_init(void *self) 876{ 877 //struct MetaDataExtraction_interface *this = 878 // (struct MetaDataExtraction_interface *) self; 879} 880 881static void MetaDataTraversal_init(void *self) 882{ 883 //struct MetaDataTraversal_interface *this = 884 // (struct MetaDataTraversal_interface *) self; 885} 886 887static void MIDIMessage_init(void *self) 888{ 889 //struct MIDIMessage_interface *this = 890 // (struct MIDIMessage_interface *) self; 891} 892 893static void MIDIMuteSolo_init(void *self) 894{ 895 //struct MIDIMuteSolo_interface *this = 896 // (struct MIDIMuteSolo_interface *) self; 897} 898 899static void MIDITempo_init(void *self) 900{ 901 //struct MIDITempo_interface *this = 902 // (struct MIDITempo_interface *) self; 903} 904 905static void MIDITime_init(void *self) 906{ 907 //struct MIDITime_interface *this = 908 // (struct MIDITime_interface *) self; 909} 910 911static void MuteSolo_init(void *self) 912{ 913 //struct MuteSolo_interface *this = 914 // (struct MuteSolo_interface *) self; 915} 916 917static void PrefetchStatus_init(void *self) 918{ 919 //struct PrefetchStatus_interface *this = 920 // (struct PrefetchStatus_interface *) self; 921} 922 923static void Object_init(void *self) 924{ 925 extern const struct SLObjectItf_ Object_ObjectItf; 926 struct Object_interface *this = (struct Object_interface *) self; 927 this->mItf = &Object_ObjectItf; 928 this->mState = SL_OBJECT_STATE_UNREALIZED; 929#ifndef NDEBUG 930 this->mCallback = NULL; 931 this->mContext = NULL; 932 this->mPriority = 0; 933 this->mPreemptable = SL_BOOLEAN_FALSE; 934#endif 935} 936 937static void OutputMix_init(void *self) 938{ 939 extern const struct SLOutputMixItf_ OutputMix_OutputMixItf; 940 struct OutputMix_interface *this = (struct OutputMix_interface *) self; 941 this->mItf = &OutputMix_OutputMixItf; 942#ifndef NDEBUG 943 this->mActiveMask = 0; 944 struct Track *track = &this->mTracks[0]; 945 // FIXME O(n) 946 // FIXME magic number 947 unsigned i; 948 for (i = 0; i < 32; ++i, ++track) 949 track->mPlay = NULL; 950#endif 951} 952 953#ifdef USE_OUTPUTMIXEXT 954static void OutputMixExt_init(void *self) 955{ 956 extern const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf; 957 struct OutputMixExt_interface *this = 958 (struct OutputMixExt_interface *) self; 959 this->mItf = &OutputMixExt_OutputMixExtItf; 960} 961#endif // USE_OUTPUTMIXEXT 962 963static void Pitch_init(void *self) 964{ 965 //struct Pitch_interface *this = 966 // (struct Pitch_interface *) self; 967} 968 969static void Play_init(void *self) 970{ 971 extern const struct SLPlayItf_ Play_PlayItf; 972 struct Play_interface *this = (struct Play_interface *) self; 973 this->mItf = &Play_PlayItf; 974 this->mState = SL_PLAYSTATE_STOPPED; 975 this->mDuration = SL_TIME_UNKNOWN; 976#ifndef NDEBUG 977 this->mPosition = (SLmillisecond) 0; 978 // this->mPlay.mPositionSamples = 0; 979 this->mCallback = NULL; 980 this->mContext = NULL; 981 this->mEventFlags = 0; 982 this->mMarkerPosition = 0; 983 this->mPositionUpdatePeriod = 0; 984#endif 985} 986 987static void PlaybackRate_init(void *self) 988{ 989 //struct PlaybackRate_interface *this = 990 // (struct PlaybackRate_interface *) self; 991} 992 993static void PresetReverb_init(void *self) 994{ 995 //struct PresetReverb_interface *this = 996 //(struct PresetReverb_interface *) self; 997} 998 999static void RatePitch_init(void *self) 1000{ 1001 //struct RatePitch_interface *this = 1002 // (struct RatePitch_interface *) self; 1003} 1004 1005static void Record_init(void *self) 1006{ 1007 //struct Record_interface *this = (struct Record_interface *) self; 1008} 1009 1010static void Seek_init(void *self) 1011{ 1012 extern const struct SLSeekItf_ Seek_SeekItf; 1013 struct Seek_interface *this = (struct Seek_interface *) self; 1014 this->mItf = &Seek_SeekItf; 1015 this->mPos = (SLmillisecond) -1; 1016 this->mStartPos = (SLmillisecond) -1; 1017 this->mEndPos = (SLmillisecond) -1; 1018#ifndef NDEBUG 1019 this->mLoopEnabled = SL_BOOLEAN_FALSE; 1020#endif 1021} 1022 1023static void ThreadSync_init(void *self) 1024{ 1025 extern const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf; 1026 struct ThreadSync_interface *this = 1027 (struct ThreadSync_interface *) self; 1028 this->mItf = &ThreadSync_ThreadSyncItf; 1029} 1030 1031static void Virtualizer_init(void *self) 1032{ 1033 //struct Virtualizer_interface *this = 1034 // (struct Virtualizer_interface *) self; 1035} 1036 1037static void Vibra_init(void *self) 1038{ 1039 extern const struct SLVibraItf_ Vibra_VibraItf; 1040 struct Vibra_interface *this = (struct Vibra_interface *) self; 1041 this->mItf = &Vibra_VibraItf; 1042} 1043 1044static void Visualization_init(void *self) 1045{ 1046 extern const struct SLVisualizationItf_ Visualization_VisualizationItf; 1047 struct Visualization_interface *this = 1048 (struct Visualization_interface *) self; 1049 this->mItf = &Visualization_VisualizationItf; 1050#ifndef NDEBUG 1051 this->mCallback = NULL; 1052 this->mContext = NULL; 1053 this->mRate = 0; 1054#endif 1055} 1056 1057static void Volume_init(void *self) 1058{ 1059 extern const struct SLVolumeItf_ Volume_VolumeItf; 1060 struct Volume_interface *this = (struct Volume_interface *) self; 1061 this->mItf = &Volume_VolumeItf; 1062#ifndef NDEBUG 1063 this->mLevel = 0; // FIXME correct ? 1064 this->mMute = SL_BOOLEAN_FALSE; 1065 this->mEnableStereoPosition = SL_BOOLEAN_FALSE; 1066 this->mStereoPosition = 0; 1067#endif 1068} 1069 1070static const struct MPH_init { 1071 // unsigned char mMPH; 1072 VoidHook mInit; 1073 VoidHook mDeinit; 1074} MPH_init_table[MPH_MAX] = { 1075 { /* MPH_3DCOMMIT, */ _3DCommit_init, NULL }, 1076 { /* MPH_3DDOPPLER, */ _3DDoppler_init, NULL }, 1077 { /* MPH_3DGROUPING, */ _3DGrouping_init, NULL }, 1078 { /* MPH_3DLOCATION, */ _3DLocation_init, NULL }, 1079 { /* MPH_3DMACROSCOPIC, */ _3DMacroscopic_init, NULL }, 1080 { /* MPH_3DSOURCE, */ _3DSource_init, NULL }, 1081 { /* MPH_AUDIODECODERCAPABILITIES, */ AudioDecoderCapabilities_init, NULL }, 1082 { /* MPH_AUDIOENCODER, */ AudioEncoder_init, NULL }, 1083 { /* MPH_AUDIOENCODERCAPABILITIES, */ AudioEncoderCapabilities_init, NULL }, 1084 { /* MPH_AUDIOIODEVICECAPABILITIES, */ AudioIODeviceCapabilities_init, 1085 NULL }, 1086 { /* MPH_BASSBOOST, */ BassBoost_init, NULL }, 1087 { /* MPH_BUFFERQUEUE, */ BufferQueue_init, NULL }, 1088 { /* MPH_DEVICEVOLUME, */ DeviceVolume_init, NULL }, 1089 { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ DynamicInterfaceManagement_init, 1090 NULL }, 1091 { /* MPH_DYNAMICSOURCE, */ DynamicSource_init, NULL }, 1092 { /* MPH_EFFECTSEND, */ EffectSend_init, NULL }, 1093 { /* MPH_ENGINE, */ Engine_init, NULL }, 1094 { /* MPH_ENGINECAPABILITIES, */ EngineCapabilities_init, NULL }, 1095 { /* MPH_ENVIRONMENTALREVERB, */ EnvironmentalReverb_init, NULL }, 1096 { /* MPH_EQUALIZER, */ Equalizer_init, NULL }, 1097 { /* MPH_LED, */ LEDArray_init, NULL }, 1098 { /* MPH_METADATAEXTRACTION, */ MetaDataExtraction_init, NULL }, 1099 { /* MPH_METADATATRAVERSAL, */ MetaDataTraversal_init, NULL }, 1100 { /* MPH_MIDIMESSAGE, */ MIDIMessage_init, NULL }, 1101 { /* MPH_MIDITIME, */ MIDITime_init, NULL }, 1102 { /* MPH_MIDITEMPO, */ MIDITempo_init, NULL }, 1103 { /* MPH_MIDIMUTESOLO, */ MIDIMuteSolo_init, NULL }, 1104 { /* MPH_MUTESOLO, */ MuteSolo_init, NULL }, 1105 { /* MPH_NULL, */ NULL, NULL }, 1106 { /* MPH_OBJECT, */ Object_init, NULL }, 1107 { /* MPH_OUTPUTMIX, */ OutputMix_init, NULL }, 1108 { /* MPH_PITCH, */ Pitch_init, NULL }, 1109 { /* MPH_PLAY, */ Play_init, NULL }, 1110 { /* MPH_PLAYBACKRATE, */ PlaybackRate_init, NULL }, 1111 { /* MPH_PREFETCHSTATUS, */ PrefetchStatus_init, NULL }, 1112 { /* MPH_PRESETREVERB, */ PresetReverb_init, NULL }, 1113 { /* MPH_RATEPITCH, */ RatePitch_init, NULL }, 1114 { /* MPH_RECORD, */ Record_init, NULL }, 1115 { /* MPH_SEEK, */ Seek_init, NULL }, 1116 { /* MPH_THREADSYNC, */ ThreadSync_init, NULL }, 1117 { /* MPH_VIBRA, */ Vibra_init, NULL }, 1118 { /* MPH_VIRTUALIZER, */ Virtualizer_init, NULL }, 1119 { /* MPH_VISUALIZATION, */ Visualization_init, NULL }, 1120 { /* MPH_VOLUME, */ Volume_init, NULL }, 1121 { /* MPH_OUTPUTMIXEXT, */ 1122#ifdef USE_OUTPUTMIXEXT 1123 OutputMixExt_init, NULL 1124#else 1125 NULL, NULL 1126#endif 1127 } 1128}; 1129 1130/* Classes vs. interfaces */ 1131 1132// 3DGroup class 1133 1134static const struct iid_vtable _3DGroup_interfaces[] = { 1135 {MPH_OBJECT, INTERFACE_IMPLICIT, 1136 offsetof(struct _3DGroup_class, mObject)}, 1137 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1138 offsetof(struct _3DGroup_class, mDynamicInterfaceManagement)}, 1139 {MPH_3DLOCATION, INTERFACE_IMPLICIT, 1140 offsetof(struct _3DGroup_class, m3DLocation)}, 1141 {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME, 1142 offsetof(struct _3DGroup_class, m3DDoppler)}, 1143 {MPH_3DSOURCE, INTERFACE_GAME, 1144 offsetof(struct _3DGroup_class, m3DSource)}, 1145 {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL, 1146 offsetof(struct _3DGroup_class, m3DMacroscopic)}, 1147}; 1148 1149static const struct class_ _3DGroup_class = { 1150 _3DGroup_interfaces, 1151 sizeof(_3DGroup_interfaces)/sizeof(_3DGroup_interfaces[0]), 1152 MPH_to_3DGroup, 1153 //"3DGroup", 1154 sizeof(struct _3DGroup_class), 1155 SL_OBJECTID_3DGROUP, 1156 NULL, 1157 NULL 1158}; 1159 1160// AudioPlayer class 1161 1162/* AudioPlayer private functions */ 1163 1164#ifdef USE_SNDFILE 1165 1166// FIXME should run this asynchronously esp. for socket fd, not on mix thread 1167static void SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext) 1168{ 1169 struct SndFile *this = (struct SndFile *) pContext; 1170 SLresult result; 1171 if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) { 1172 result = (*caller)->Enqueue(caller, this->mRetryBuffer, 1173 this->mRetrySize); 1174 if (SL_RESULT_BUFFER_INSUFFICIENT == result) 1175 return; // what, again? 1176 assert(SL_RESULT_SUCCESS == result); 1177 this->mRetryBuffer = NULL; 1178 this->mRetrySize = 0; 1179 return; 1180 } 1181 short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1; 1182 this->mIs0 ^= SL_BOOLEAN_TRUE; 1183 sf_count_t count; 1184 // FIXME magic number 1185 count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512); 1186 if (0 < count) { 1187 SLuint32 size = count * sizeof(short); 1188 // FIXME if we had an internal API, could call this directly 1189 result = (*caller)->Enqueue(caller, pBuffer, size); 1190 if (SL_RESULT_BUFFER_INSUFFICIENT == result) { 1191 this->mRetryBuffer = pBuffer; 1192 this->mRetrySize = size; 1193 return; 1194 } 1195 assert(SL_RESULT_SUCCESS == result); 1196 } 1197} 1198 1199static SLboolean SndFile_IsSupported(const SF_INFO *sfinfo) 1200{ 1201 switch (sfinfo->format & SF_FORMAT_TYPEMASK) { 1202 case SF_FORMAT_WAV: 1203 break; 1204 default: 1205 return SL_BOOLEAN_FALSE; 1206 } 1207 switch (sfinfo->format & SF_FORMAT_SUBMASK) { 1208 case SF_FORMAT_PCM_16: 1209 break; 1210 default: 1211 return SL_BOOLEAN_FALSE; 1212 } 1213 switch (sfinfo->samplerate) { 1214 case 44100: 1215 break; 1216 default: 1217 return SL_BOOLEAN_FALSE; 1218 } 1219 switch (sfinfo->channels) { 1220 case 2: 1221 break; 1222 default: 1223 return SL_BOOLEAN_FALSE; 1224 } 1225 return SL_BOOLEAN_TRUE; 1226} 1227 1228#endif // USE_SNDFILE 1229 1230#if 0 1231/*static*/ const struct SLObjectItf_ AudioPlayer_ObjectItf = { 1232 Object_Realize, 1233 Object_Resume, 1234 Object_GetState, 1235 Object_GetInterface, 1236 Object_RegisterCallback, 1237 Object_AbortAsyncOperation, 1238 Object_Destroy, 1239 Object_SetPriority, 1240 Object_GetPriority, 1241 Object_SetLossOfControlInterfaces, 1242}; 1243#endif 1244 1245static SLresult AudioPlayer_Realize(void *self) 1246{ 1247 struct AudioPlayer_class *this = (struct AudioPlayer_class *) self; 1248 SLresult result = SL_RESULT_SUCCESS; 1249 // for Android here is where we do setDataSource etc. for MediaPlayer 1250#ifdef USE_SNDFILE 1251 if (NULL != this->mSndFile.mPathname) { 1252 SF_INFO sfinfo; 1253 sfinfo.format = 0; 1254 this->mSndFile.mSNDFILE = sf_open( 1255 (const char *) this->mSndFile.mPathname, SFM_READ, &sfinfo); 1256 if (NULL == this->mSndFile.mSNDFILE) { 1257 result = SL_RESULT_CONTENT_NOT_FOUND; 1258 } else if (!SndFile_IsSupported(&sfinfo)) { 1259 sf_close(this->mSndFile.mSNDFILE); 1260 this->mSndFile.mSNDFILE = NULL; 1261 result = SL_RESULT_CONTENT_UNSUPPORTED; 1262 } else { 1263 SLBufferQueueItf bufferQueue = &this->mBufferQueue.mItf; 1264 // FIXME should use a private internal API, and disallow 1265 // application to have access to our buffer queue 1266 // FIXME if we had an internal API, could call this directly 1267 result = (*bufferQueue)->RegisterCallback(bufferQueue, 1268 SndFile_Callback, &this->mSndFile); 1269 } 1270 } 1271#endif // USE_SNDFILE 1272 return result; 1273} 1274 1275static void AudioPlayer_Destroy(void *self) 1276{ 1277 struct AudioPlayer_class *this = (struct AudioPlayer_class *) self; 1278 // FIXME stop the player in a way that app can't restart it 1279 // Free the buffer queue, if it was larger than typical 1280 if (NULL != this->mBufferQueue.mArray && 1281 this->mBufferQueue.mArray != this->mBufferQueue.mTypical) { 1282 free(this->mBufferQueue.mArray); 1283 this->mBufferQueue.mArray = NULL; 1284 } 1285#ifdef USE_SNDFILE 1286 if (NULL != this->mSndFile.mSNDFILE) { 1287 sf_close(this->mSndFile.mSNDFILE); 1288 this->mSndFile.mSNDFILE = NULL; 1289 } 1290#endif // USE_SNDFILE 1291} 1292 1293static const struct iid_vtable AudioPlayer_interfaces[] = { 1294 {MPH_OBJECT, INTERFACE_IMPLICIT, 1295 offsetof(struct AudioPlayer_class, mObject)}, 1296 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1297 offsetof(struct AudioPlayer_class, mDynamicInterfaceManagement)}, 1298 {MPH_PLAY, INTERFACE_IMPLICIT, 1299 offsetof(struct AudioPlayer_class, mPlay)}, 1300 {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME, 1301 offsetof(struct AudioPlayer_class, m3DDoppler)}, 1302 {MPH_3DGROUPING, INTERFACE_GAME, 1303 offsetof(struct AudioPlayer_class, m3DGrouping)}, 1304 {MPH_3DLOCATION, INTERFACE_GAME, 1305 offsetof(struct AudioPlayer_class, m3DLocation)}, 1306 {MPH_3DSOURCE, INTERFACE_GAME, 1307 offsetof(struct AudioPlayer_class, m3DSource)}, 1308 // FIXME Currently we create an internal buffer queue for playing files 1309 {MPH_BUFFERQUEUE, /* INTERFACE_GAME */ INTERFACE_IMPLICIT, 1310 offsetof(struct AudioPlayer_class, mBufferQueue)}, 1311 {MPH_EFFECTSEND, INTERFACE_MUSIC_GAME, 1312 offsetof(struct AudioPlayer_class, mEffectSend)}, 1313 {MPH_MUTESOLO, INTERFACE_GAME, 1314 offsetof(struct AudioPlayer_class, mMuteSolo)}, 1315 {MPH_METADATAEXTRACTION, INTERFACE_MUSIC_GAME, 1316 offsetof(struct AudioPlayer_class, mMetaDataExtraction)}, 1317 {MPH_METADATATRAVERSAL, INTERFACE_MUSIC_GAME, 1318 offsetof(struct AudioPlayer_class, mMetaDataTraversal)}, 1319 {MPH_PREFETCHSTATUS, INTERFACE_TBD, 1320 offsetof(struct AudioPlayer_class, mPrefetchStatus)}, 1321 {MPH_RATEPITCH, INTERFACE_DYNAMIC_GAME, 1322 offsetof(struct AudioPlayer_class, mRatePitch)}, 1323 {MPH_SEEK, INTERFACE_TBD, 1324 offsetof(struct AudioPlayer_class, mSeek)}, 1325 {MPH_VOLUME, INTERFACE_TBD, 1326 offsetof(struct AudioPlayer_class, mVolume)}, 1327 {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL, 1328 offsetof(struct AudioPlayer_class, m3DMacroscopic)}, 1329 {MPH_BASSBOOST, INTERFACE_OPTIONAL, 1330 offsetof(struct AudioPlayer_class, mBassBoost)}, 1331 {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL, 1332 offsetof(struct AudioPlayer_class, mDynamicSource)}, 1333 {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL, 1334 offsetof(struct AudioPlayer_class, mEnvironmentalReverb)}, 1335 {MPH_EQUALIZER, INTERFACE_OPTIONAL, 1336 offsetof(struct AudioPlayer_class, mEqualizer)}, 1337 {MPH_PITCH, INTERFACE_OPTIONAL, 1338 offsetof(struct AudioPlayer_class, mPitch)}, 1339 {MPH_PRESETREVERB, INTERFACE_OPTIONAL, 1340 offsetof(struct AudioPlayer_class, mPresetReverb)}, 1341 {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL, 1342 offsetof(struct AudioPlayer_class, mPlaybackRate)}, 1343 {MPH_VIRTUALIZER, INTERFACE_OPTIONAL, 1344 offsetof(struct AudioPlayer_class, mVirtualizer)}, 1345 {MPH_VISUALIZATION, INTERFACE_OPTIONAL, 1346 offsetof(struct AudioPlayer_class, mVisualization)} 1347}; 1348 1349static const struct class_ AudioPlayer_class = { 1350 AudioPlayer_interfaces, 1351 sizeof(AudioPlayer_interfaces)/sizeof(AudioPlayer_interfaces[0]), 1352 MPH_to_AudioPlayer, 1353 //"AudioPlayer", 1354 sizeof(struct AudioPlayer_class), 1355 SL_OBJECTID_AUDIOPLAYER, 1356 AudioPlayer_Realize, 1357 AudioPlayer_Destroy 1358}; 1359 1360// AudioRecorder class 1361 1362static const struct iid_vtable AudioRecorder_interfaces[] = { 1363 {MPH_OBJECT, INTERFACE_IMPLICIT, 1364 offsetof(struct AudioRecorder_class, mObject)}, 1365 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1366 offsetof(struct AudioRecorder_class, mDynamicInterfaceManagement)}, 1367 {MPH_RECORD, INTERFACE_IMPLICIT, 1368 offsetof(struct AudioRecorder_class, mRecord)}, 1369 {MPH_AUDIOENCODER, INTERFACE_TBD, 1370 offsetof(struct AudioRecorder_class, mAudioEncoder)}, 1371 {MPH_BASSBOOST, INTERFACE_OPTIONAL, 1372 offsetof(struct AudioRecorder_class, mBassBoost)}, 1373 {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL, 1374 offsetof(struct AudioRecorder_class, mDynamicSource)}, 1375 {MPH_EQUALIZER, INTERFACE_OPTIONAL, 1376 offsetof(struct AudioRecorder_class, mEqualizer)}, 1377 {MPH_VISUALIZATION, INTERFACE_OPTIONAL, 1378 offsetof(struct AudioRecorder_class, mVisualization)}, 1379 {MPH_VOLUME, INTERFACE_OPTIONAL, 1380 offsetof(struct AudioRecorder_class, mVolume)} 1381}; 1382 1383static const struct class_ AudioRecorder_class = { 1384 AudioRecorder_interfaces, 1385 sizeof(AudioRecorder_interfaces)/sizeof(AudioRecorder_interfaces[0]), 1386 MPH_to_AudioRecorder, 1387 //"AudioRecorder", 1388 sizeof(struct AudioRecorder_class), 1389 SL_OBJECTID_AUDIORECORDER, 1390 NULL, 1391 NULL 1392}; 1393 1394// Engine class 1395 1396static const struct iid_vtable Engine_interfaces[] = { 1397 {MPH_OBJECT, INTERFACE_IMPLICIT, 1398 offsetof(struct Engine_class, mObject)}, 1399 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1400 offsetof(struct Engine_class, mDynamicInterfaceManagement)}, 1401 {MPH_ENGINE, INTERFACE_IMPLICIT, 1402 offsetof(struct Engine_class, mEngine)}, 1403 {MPH_ENGINECAPABILITIES, INTERFACE_IMPLICIT, 1404 offsetof(struct Engine_class, mEngineCapabilities)}, 1405 {MPH_THREADSYNC, INTERFACE_IMPLICIT, 1406 offsetof(struct Engine_class, mThreadSync)}, 1407 {MPH_AUDIOIODEVICECAPABILITIES, INTERFACE_IMPLICIT, 1408 offsetof(struct Engine_class, mAudioIODeviceCapabilities)}, 1409 {MPH_AUDIODECODERCAPABILITIES, INTERFACE_EXPLICIT, 1410 offsetof(struct Engine_class, mAudioDecoderCapabilities)}, 1411 {MPH_AUDIOENCODERCAPABILITIES, INTERFACE_EXPLICIT, 1412 offsetof(struct Engine_class, mAudioEncoderCapabilities)}, 1413 {MPH_3DCOMMIT, INTERFACE_EXPLICIT_GAME, 1414 offsetof(struct Engine_class, m3DCommit)}, 1415 {MPH_DEVICEVOLUME, INTERFACE_OPTIONAL, 1416 offsetof(struct Engine_class, mDeviceVolume)} 1417}; 1418 1419static const struct class_ Engine_class = { 1420 Engine_interfaces, 1421 sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]), 1422 MPH_to_Engine, 1423 //"Engine", 1424 sizeof(struct Engine_class), 1425 SL_OBJECTID_ENGINE, 1426 NULL, 1427 NULL 1428}; 1429 1430// LEDDevice class 1431 1432static const struct iid_vtable LEDDevice_interfaces[] = { 1433 {MPH_OBJECT, INTERFACE_IMPLICIT, 1434 offsetof(struct LEDDevice_class, mObject)}, 1435 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1436 offsetof(struct LEDDevice_class, mDynamicInterfaceManagement)}, 1437 {MPH_LED, INTERFACE_IMPLICIT, 1438 offsetof(struct LEDDevice_class, mLED)} 1439}; 1440 1441static const struct class_ LEDDevice_class = { 1442 LEDDevice_interfaces, 1443 sizeof(LEDDevice_interfaces)/sizeof(LEDDevice_interfaces[0]), 1444 MPH_to_LEDDevice, 1445 //"LEDDevice", 1446 sizeof(struct LEDDevice_class), 1447 SL_OBJECTID_LEDDEVICE, 1448 NULL, 1449 NULL 1450}; 1451 1452// Listener class 1453 1454static const struct iid_vtable Listener_interfaces[] = { 1455 {MPH_OBJECT, INTERFACE_IMPLICIT, 1456 offsetof(struct Listener_class, mObject)}, 1457 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1458 offsetof(struct Listener_class, mDynamicInterfaceManagement)}, 1459 {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME, 1460 offsetof(struct _3DGroup_class, m3DDoppler)}, 1461 {MPH_3DLOCATION, INTERFACE_EXPLICIT_GAME, 1462 offsetof(struct _3DGroup_class, m3DLocation)} 1463}; 1464 1465static const struct class_ Listener_class = { 1466 Listener_interfaces, 1467 sizeof(Listener_interfaces)/sizeof(Listener_interfaces[0]), 1468 MPH_to_Listener, 1469 //"Listener", 1470 sizeof(struct Listener_class), 1471 SL_OBJECTID_LISTENER, 1472 NULL, 1473 NULL 1474}; 1475 1476// MetadataExtractor class 1477 1478static const struct iid_vtable MetadataExtractor_interfaces[] = { 1479 {MPH_OBJECT, INTERFACE_IMPLICIT, 1480 offsetof(struct MetadataExtractor_class, mObject)}, 1481 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1482 offsetof(struct MetadataExtractor_class, mDynamicInterfaceManagement)}, 1483 {MPH_DYNAMICSOURCE, INTERFACE_IMPLICIT, 1484 offsetof(struct MetadataExtractor_class, mDynamicSource)}, 1485 {MPH_METADATAEXTRACTION, INTERFACE_IMPLICIT, 1486 offsetof(struct MetadataExtractor_class, mMetaDataExtraction)}, 1487 {MPH_METADATATRAVERSAL, INTERFACE_IMPLICIT, 1488 offsetof(struct MetadataExtractor_class, mMetaDataTraversal)} 1489}; 1490 1491static const struct class_ MetadataExtractor_class = { 1492 MetadataExtractor_interfaces, 1493 sizeof(MetadataExtractor_interfaces) / 1494 sizeof(MetadataExtractor_interfaces[0]), 1495 MPH_to_MetadataExtractor, 1496 //"MetadataExtractor", 1497 sizeof(struct MetadataExtractor_class), 1498 SL_OBJECTID_METADATAEXTRACTOR, 1499 NULL, 1500 NULL 1501}; 1502 1503// MidiPlayer class 1504 1505static const struct iid_vtable MidiPlayer_interfaces[] = { 1506 {MPH_OBJECT, INTERFACE_IMPLICIT, 1507 offsetof(struct MidiPlayer_class, mObject)}, 1508 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1509 offsetof(struct MidiPlayer_class, mDynamicInterfaceManagement)}, 1510 {MPH_PLAY, INTERFACE_IMPLICIT, 1511 offsetof(struct MidiPlayer_class, mPlay)}, 1512 {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME, 1513 offsetof(struct _3DGroup_class, m3DDoppler)}, 1514 {MPH_3DGROUPING, INTERFACE_GAME, 1515 offsetof(struct MidiPlayer_class, m3DGrouping)}, 1516 {MPH_3DLOCATION, INTERFACE_GAME, 1517 offsetof(struct MidiPlayer_class, m3DLocation)}, 1518 {MPH_3DSOURCE, INTERFACE_GAME, 1519 offsetof(struct MidiPlayer_class, m3DSource)}, 1520 {MPH_BUFFERQUEUE, INTERFACE_GAME, 1521 offsetof(struct MidiPlayer_class, mBufferQueue)}, 1522 {MPH_EFFECTSEND, INTERFACE_GAME, 1523 offsetof(struct MidiPlayer_class, mEffectSend)}, 1524 {MPH_MUTESOLO, INTERFACE_GAME, 1525 offsetof(struct MidiPlayer_class, mMuteSolo)}, 1526 {MPH_METADATAEXTRACTION, INTERFACE_GAME, 1527 offsetof(struct MidiPlayer_class, mMetaDataExtraction)}, 1528 {MPH_METADATATRAVERSAL, INTERFACE_GAME, 1529 offsetof(struct MidiPlayer_class, mMetaDataTraversal)}, 1530 {MPH_MIDIMESSAGE, INTERFACE_PHONE_GAME, 1531 offsetof(struct MidiPlayer_class, mMIDIMessage)}, 1532 {MPH_MIDITIME, INTERFACE_PHONE_GAME, 1533 offsetof(struct MidiPlayer_class, mMIDITime)}, 1534 {MPH_MIDITEMPO, INTERFACE_PHONE_GAME, 1535 offsetof(struct MidiPlayer_class, mMIDITempo)}, 1536 {MPH_MIDIMUTESOLO, INTERFACE_GAME, 1537 offsetof(struct MidiPlayer_class, mMIDIMuteSolo)}, 1538 {MPH_PREFETCHSTATUS, INTERFACE_PHONE_GAME, 1539 offsetof(struct MidiPlayer_class, mPrefetchStatus)}, 1540 {MPH_SEEK, INTERFACE_PHONE_GAME, 1541 offsetof(struct MidiPlayer_class, mSeek)}, 1542 {MPH_VOLUME, INTERFACE_PHONE_GAME, 1543 offsetof(struct MidiPlayer_class, mVolume)}, 1544 {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL, 1545 offsetof(struct MidiPlayer_class, m3DMacroscopic)}, 1546 {MPH_BASSBOOST, INTERFACE_OPTIONAL, 1547 offsetof(struct MidiPlayer_class, mBassBoost)}, 1548 {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL, 1549 offsetof(struct MidiPlayer_class, mDynamicSource)}, 1550 {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL, 1551 offsetof(struct MidiPlayer_class, mEnvironmentalReverb)}, 1552 {MPH_EQUALIZER, INTERFACE_OPTIONAL, 1553 offsetof(struct MidiPlayer_class, mEqualizer)}, 1554 {MPH_PITCH, INTERFACE_OPTIONAL, 1555 offsetof(struct MidiPlayer_class, mPitch)}, 1556 {MPH_PRESETREVERB, INTERFACE_OPTIONAL, 1557 offsetof(struct MidiPlayer_class, mPresetReverb)}, 1558 {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL, 1559 offsetof(struct MidiPlayer_class, mPlaybackRate)}, 1560 {MPH_VIRTUALIZER, INTERFACE_OPTIONAL, 1561 offsetof(struct MidiPlayer_class, mVirtualizer)}, 1562 {MPH_VISUALIZATION, INTERFACE_OPTIONAL, 1563 offsetof(struct MidiPlayer_class, mVisualization)} 1564}; 1565 1566static const struct class_ MidiPlayer_class = { 1567 MidiPlayer_interfaces, 1568 sizeof(MidiPlayer_interfaces)/sizeof(MidiPlayer_interfaces[0]), 1569 MPH_to_MidiPlayer, 1570 //"MidiPlayer", 1571 sizeof(struct MidiPlayer_class), 1572 SL_OBJECTID_MIDIPLAYER, 1573 NULL, 1574 NULL 1575}; 1576 1577// OutputMix class 1578 1579static const struct iid_vtable OutputMix_interfaces[] = { 1580 {MPH_OBJECT, INTERFACE_IMPLICIT, 1581 offsetof(struct OutputMix_class, mObject)}, 1582 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT, 1583 offsetof(struct OutputMix_class, mDynamicInterfaceManagement)}, 1584 {MPH_OUTPUTMIX, INTERFACE_IMPLICIT, 1585 offsetof(struct OutputMix_class, mOutputMix)}, 1586#ifdef USE_OUTPUTMIXEXT 1587 {MPH_OUTPUTMIXEXT, INTERFACE_IMPLICIT, 1588 offsetof(struct OutputMix_class, mOutputMixExt)}, 1589#else 1590 {MPH_OUTPUTMIXEXT, INTERFACE_TBD /*NOT AVAIL*/, 0}, 1591#endif 1592 {MPH_ENVIRONMENTALREVERB, INTERFACE_DYNAMIC_GAME, 1593 offsetof(struct OutputMix_class, mEnvironmentalReverb)}, 1594 {MPH_EQUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME, 1595 offsetof(struct OutputMix_class, mEqualizer)}, 1596 {MPH_PRESETREVERB, INTERFACE_DYNAMIC_MUSIC, 1597 offsetof(struct OutputMix_class, mPresetReverb)}, 1598 {MPH_VIRTUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME, 1599 offsetof(struct OutputMix_class, mVirtualizer)}, 1600 {MPH_VOLUME, INTERFACE_GAME_MUSIC, 1601 offsetof(struct OutputMix_class, mVolume)}, 1602 {MPH_BASSBOOST, INTERFACE_OPTIONAL_DYNAMIC, 1603 offsetof(struct OutputMix_class, mBassBoost)}, 1604 {MPH_VISUALIZATION, INTERFACE_OPTIONAL, 1605 offsetof(struct OutputMix_class, mVisualization)} 1606}; 1607 1608static const struct class_ OutputMix_class = { 1609 OutputMix_interfaces, 1610 sizeof(OutputMix_interfaces)/sizeof(OutputMix_interfaces[0]), 1611 MPH_to_OutputMix, 1612 //"OutputMix", 1613 sizeof(struct OutputMix_class), 1614 SL_OBJECTID_OUTPUTMIX, 1615 NULL, 1616 NULL 1617}; 1618 1619// Vibra class 1620 1621static const struct iid_vtable VibraDevice_interfaces[] = { 1622 {MPH_OBJECT, INTERFACE_OPTIONAL, 1623 offsetof(struct VibraDevice_class, mObject)}, 1624 {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_OPTIONAL, 1625 offsetof(struct VibraDevice_class, mDynamicInterfaceManagement)}, 1626 {MPH_VIBRA, INTERFACE_OPTIONAL, 1627 offsetof(struct VibraDevice_class, mVibra)} 1628}; 1629 1630static const struct class_ VibraDevice_class = { 1631 VibraDevice_interfaces, 1632 sizeof(VibraDevice_interfaces)/sizeof(VibraDevice_interfaces[0]), 1633 MPH_to_Vibra, 1634 //"VibraDevice", 1635 sizeof(struct VibraDevice_class), 1636 SL_OBJECTID_VIBRADEVICE, 1637 NULL, 1638 NULL 1639}; 1640 1641/* Map SL_OBJECTID to class */ 1642 1643static const struct class_ * const classes[] = { 1644 // Do not change order of these entries; they are in numerical order 1645 &Engine_class, 1646 &LEDDevice_class, 1647 &AudioPlayer_class, 1648 &AudioRecorder_class, 1649 &MidiPlayer_class, 1650 &Listener_class, 1651 &_3DGroup_class, 1652 &VibraDevice_class, 1653 &OutputMix_class, 1654 &MetadataExtractor_class 1655}; 1656 1657static const struct class_ *objectIDtoClass(SLuint32 objectID) 1658{ 1659 SLuint32 objectID0 = classes[0]->mObjectID; 1660 if (objectID0 <= objectID && 1661 classes[sizeof(classes)/sizeof(classes[0])-1]->mObjectID >= objectID) 1662 return classes[objectID - objectID0]; 1663 return NULL; 1664} 1665 1666// Construct a new instance of the specified class, exposing selected interfaces 1667 1668static void *construct(const struct class_ *class__, unsigned exposedMask) 1669{ 1670 void *this; 1671#ifndef NDEBUG 1672 this = malloc(class__->mSize); 1673#else 1674 this = calloc(1, class__->mSize); 1675#endif 1676 if (NULL != this) { 1677#ifndef NDEBUG 1678 // for debugging, to detect uninitialized fields 1679 memset(this, 0x55, class__->mSize); 1680#endif 1681 ((struct Object_interface *) this)->mClass = class__; 1682 ((struct Object_interface *) this)->mExposedMask = exposedMask; 1683 const struct iid_vtable *x = class__->mInterfaces; 1684 unsigned i; 1685 for (i = 0; exposedMask; ++i, ++x, exposedMask >>= 1) { 1686 if (exposedMask & 1) { 1687 unsigned MPH = x->mMPH; 1688 size_t offset = x->mOffset; 1689 void *self = (char *) this + offset; 1690 ((void **) self)[1] = this; 1691 VoidHook init = MPH_init_table[MPH].mInit; 1692 if (NULL != init) 1693 (*init)(self); 1694 } 1695 } 1696 } 1697 return this; 1698} 1699 1700/* Interface implementations */ 1701 1702// FIXME Sort by interface 1703 1704/* Object implementation */ 1705 1706static SLresult Object_Realize(SLObjectItf self, SLboolean async) 1707{ 1708 struct Object_interface *this = (struct Object_interface *) self; 1709 // FIXME locking needed here in case two threads call Realize at once 1710 if (SL_OBJECT_STATE_UNREALIZED != this->mState) 1711 return SL_RESULT_PRECONDITIONS_VIOLATED; 1712 const struct class_ *class__ = this->mClass; 1713 StatusHook realize = class__->mRealize; 1714 SLresult result; 1715 // FIXME This should be done asynchronously if requested 1716 result = NULL != realize ? (*realize)(this) : SL_RESULT_SUCCESS; 1717 if (SL_RESULT_SUCCESS == result) 1718 this->mState = SL_OBJECT_STATE_REALIZED; 1719 if (async && NULL != this->mCallback) 1720 (*this->mCallback)(self, this->mContext, 1721 SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mState, NULL); 1722 return result; 1723} 1724 1725static SLresult Object_Resume(SLObjectItf self, SLboolean async) 1726{ 1727 // FIXME process async callback 1728 return SL_RESULT_SUCCESS; 1729} 1730 1731static SLresult Object_GetState(SLObjectItf self, SLuint32 *pState) 1732{ 1733 if (NULL == pState) 1734 return SL_RESULT_PARAMETER_INVALID; 1735 struct Object_interface *this = (struct Object_interface *) self; 1736 *pState = this->mState; 1737 return SL_RESULT_SUCCESS; 1738} 1739 1740static SLresult Object_GetInterface(SLObjectItf self, const SLInterfaceID iid, 1741 void *pInterface) 1742{ 1743 if (NULL == iid || NULL == pInterface) 1744 return SL_RESULT_PARAMETER_INVALID; 1745 struct Object_interface *this = (struct Object_interface *) self; 1746 if (SL_OBJECT_STATE_REALIZED != this->mState) 1747 return SL_RESULT_PRECONDITIONS_VIOLATED; 1748 const struct class_ *class__ = this->mClass; 1749 int MPH = IID_to_MPH(iid); 1750 if (0 > MPH) 1751 return SL_RESULT_FEATURE_UNSUPPORTED; 1752 int index = class__->mMPH_to_index[MPH]; 1753 if (0 > index) 1754 return SL_RESULT_FEATURE_UNSUPPORTED; 1755 unsigned mask = 1 << index; 1756 if (!(this->mExposedMask & mask)) 1757 return SL_RESULT_FEATURE_UNSUPPORTED; 1758// FIXME code review on 2010/04/16 1759// I think it is "this->this" instead of "this" at line ### : 1760// *(void **)pInterface = (char *) this + class__->mInterfaces[index].offset; 1761 *(void **)pInterface = (char *) this + class__->mInterfaces[index].mOffset; 1762 // FIXME Should note that interface has been gotten, 1763 // and detect use of ill-gotten interfaces 1764 return SL_RESULT_SUCCESS; 1765} 1766 1767static SLresult Object_RegisterCallback(SLObjectItf self, 1768 slObjectCallback callback, void *pContext) 1769{ 1770 struct Object_interface *this = (struct Object_interface *) self; 1771 this->mCallback = callback; 1772 this->mContext = pContext; 1773 return SL_RESULT_SUCCESS; 1774} 1775 1776static void Object_AbortAsyncOperation(SLObjectItf self) 1777{ 1778} 1779 1780static void Object_Destroy(SLObjectItf self) 1781{ 1782 Object_AbortAsyncOperation(self); 1783 struct Object_interface *this = (struct Object_interface *) self; 1784 const struct class_ *class__ = this->mClass; 1785 VoidHook destroy = class__->mDestroy; 1786 if (NULL != destroy) 1787 (*destroy)(this); 1788 // FIXME call the deinitializer for each currently exposed interface, 1789 // whether it is implicit, explicit, optional, or dynamically added 1790#ifndef NDEBUG 1791 memset(this, 0x55, this->mClass->mSize); 1792#endif 1793 // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED; 1794 free(this); 1795} 1796 1797static SLresult Object_SetPriority(SLObjectItf self, SLint32 priority, 1798 SLboolean preemptable) 1799{ 1800 struct Object_interface *this = (struct Object_interface *) self; 1801 this->mPriority = priority; 1802 this->mPreemptable = preemptable; 1803 return SL_RESULT_SUCCESS; 1804} 1805 1806static SLresult Object_GetPriority(SLObjectItf self, SLint32 *pPriority, 1807 SLboolean *pPreemptable) 1808{ 1809 if (NULL == pPriority || NULL == pPreemptable) 1810 return SL_RESULT_PARAMETER_INVALID; 1811 struct Object_interface *this = (struct Object_interface *) self; 1812 *pPriority = this->mPriority; 1813 *pPreemptable = this->mPreemptable; 1814 return SL_RESULT_SUCCESS; 1815} 1816 1817static SLresult Object_SetLossOfControlInterfaces(SLObjectItf self, 1818 SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled) 1819{ 1820 return SL_RESULT_SUCCESS; 1821} 1822 1823/*static*/ const struct SLObjectItf_ Object_ObjectItf = { 1824 Object_Realize, 1825 Object_Resume, 1826 Object_GetState, 1827 Object_GetInterface, 1828 Object_RegisterCallback, 1829 Object_AbortAsyncOperation, 1830 Object_Destroy, 1831 Object_SetPriority, 1832 Object_GetPriority, 1833 Object_SetLossOfControlInterfaces, 1834}; 1835 1836/* DynamicInterfaceManagement implementation */ 1837 1838static SLresult DynamicInterfaceManagement_AddInterface( 1839 SLDynamicInterfaceManagementItf self, const SLInterfaceID iid, 1840 SLboolean async) 1841{ 1842 if (NULL == iid) 1843 return SL_RESULT_PARAMETER_INVALID; 1844 struct DynamicInterfaceManagement_interface *this = 1845 (struct DynamicInterfaceManagement_interface *) self; 1846 struct Object_interface *thisObject = 1847 (struct Object_interface *) this->this; 1848 const struct class_ *class__ = thisObject->mClass; 1849 int MPH = IID_to_MPH(iid); 1850 if (0 > MPH) 1851 return SL_RESULT_FEATURE_UNSUPPORTED; 1852 int index = class__->mMPH_to_index[MPH]; 1853 if (0 > index) 1854 return SL_RESULT_FEATURE_UNSUPPORTED; 1855 unsigned mask = 1 << index; 1856 if (thisObject->mExposedMask & mask) 1857 return SL_RESULT_PRECONDITIONS_VIOLATED; 1858 // FIXME Currently do initialization here, but might be asynchronous 1859 const struct iid_vtable *x = &class__->mInterfaces[index]; 1860 size_t offset = x->mOffset; 1861 void *thisItf = (char *) thisObject + offset; 1862 size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ? 1863 class__->mSize : x[1].mOffset) - offset; 1864#ifndef NDEBUG 1865// for debugging, to detect uninitialized fields 1866#define FILLER 0x55 1867#else 1868#define FILLER 0 1869#endif 1870 memset(thisItf, FILLER, size); 1871 ((void **) thisItf)[1] = thisObject; 1872 VoidHook init = MPH_init_table[MPH].mInit; 1873 if (NULL != init) 1874 (*init)(thisItf); 1875 thisObject->mExposedMask |= mask; 1876 this->mAddedMask |= mask; 1877 SLresult result = SL_RESULT_SUCCESS; 1878 if (async && NULL != this->mCallback) { 1879 (*this->mCallback)(self, this->mContext, 1880 SL_DYNAMIC_ITF_EVENT_RESOURCES_AVAILABLE, result, iid); 1881 } 1882 return result; 1883} 1884 1885static SLresult DynamicInterfaceManagement_RemoveInterface( 1886 SLDynamicInterfaceManagementItf self, const SLInterfaceID iid) 1887{ 1888 if (NULL == iid) 1889 return SL_RESULT_PARAMETER_INVALID; 1890 struct DynamicInterfaceManagement_interface *this = 1891 (struct DynamicInterfaceManagement_interface *) self; 1892 struct Object_interface *thisObject = 1893 (struct Object_interface *) this->this; 1894 const struct class_ *class__ = thisObject->mClass; 1895 int MPH = IID_to_MPH(iid); 1896 if (MPH < 0) 1897 return SL_RESULT_PRECONDITIONS_VIOLATED; 1898 int index = class__->mMPH_to_index[MPH]; 1899 if (index < 0) 1900 return SL_RESULT_PRECONDITIONS_VIOLATED; 1901 unsigned mask = 1 << index; 1902 // disallow removal of non-dynamic interfaces 1903 if (!(this->mAddedMask & mask)) 1904 return SL_RESULT_PRECONDITIONS_VIOLATED; 1905 // FIXME Currently do de-initialization here, but might be asynchronous 1906 const struct iid_vtable *x = &class__->mInterfaces[index]; 1907 size_t offset = x->mOffset; 1908 void *thisItf = (char *) thisObject + offset; 1909 VoidHook deinit = MPH_init_table[MPH].mDeinit; 1910 if (NULL != deinit) 1911 (*deinit)(thisItf); 1912 size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ? 1913 class__->mSize : x[1].mOffset) - offset; 1914#ifndef NDEBUG 1915 memset(thisItf, 0x55, size); 1916#endif 1917 thisObject->mExposedMask &= ~mask; 1918 this->mAddedMask &= ~mask; 1919 return SL_RESULT_SUCCESS; 1920} 1921 1922static SLresult DynamicInterfaceManagement_ResumeInterface( 1923 SLDynamicInterfaceManagementItf self, 1924 const SLInterfaceID iid, SLboolean async) 1925{ 1926 return SL_RESULT_SUCCESS; 1927} 1928 1929static SLresult DynamicInterfaceManagement_RegisterCallback( 1930 SLDynamicInterfaceManagementItf self, 1931 slDynamicInterfaceManagementCallback callback, void *pContext) 1932{ 1933 struct DynamicInterfaceManagement_interface *this = 1934 (struct DynamicInterfaceManagement_interface *) self; 1935 this->mCallback = callback; 1936 this->mContext = pContext; 1937 return SL_RESULT_SUCCESS; 1938} 1939 1940/*static*/ const struct SLDynamicInterfaceManagementItf_ 1941DynamicInterfaceManagement_DynamicInterfaceManagementItf = { 1942 DynamicInterfaceManagement_AddInterface, 1943 DynamicInterfaceManagement_RemoveInterface, 1944 DynamicInterfaceManagement_ResumeInterface, 1945 DynamicInterfaceManagement_RegisterCallback 1946}; 1947 1948/* Play implementation */ 1949 1950static SLresult Play_SetPlayState(SLPlayItf self, SLuint32 state) 1951{ 1952 switch (state) { 1953 case SL_PLAYSTATE_STOPPED: 1954 case SL_PLAYSTATE_PAUSED: 1955 case SL_PLAYSTATE_PLAYING: 1956 break; 1957 default: 1958 return SL_RESULT_PARAMETER_INVALID; 1959 } 1960 struct Play_interface *this = (struct Play_interface *) self; 1961 this->mState = state; 1962 if (SL_PLAYSTATE_STOPPED == state) { 1963 this->mPosition = (SLmillisecond) 0; 1964 // this->mPositionSamples = 0; 1965 } 1966 return SL_RESULT_SUCCESS; 1967} 1968 1969static SLresult Play_GetPlayState(SLPlayItf self, SLuint32 *pState) 1970{ 1971 if (NULL == pState) 1972 return SL_RESULT_PARAMETER_INVALID; 1973 struct Play_interface *this = (struct Play_interface *) self; 1974 *pState = this->mState; 1975 return SL_RESULT_SUCCESS; 1976} 1977 1978static SLresult Play_GetDuration(SLPlayItf self, SLmillisecond *pMsec) 1979{ 1980 // FIXME: for SNDFILE only, check to see if already know duration 1981 // if so, good, otherwise save position, 1982 // read quickly to end of file, counting frames, 1983 // use sample rate to compute duration, then seek back to current position 1984 if (NULL == pMsec) 1985 return SL_RESULT_PARAMETER_INVALID; 1986 struct Play_interface *this = (struct Play_interface *) self; 1987 *pMsec = this->mDuration; 1988 return SL_RESULT_SUCCESS; 1989} 1990 1991static SLresult Play_GetPosition(SLPlayItf self, SLmillisecond *pMsec) 1992{ 1993 if (NULL == pMsec) 1994 return SL_RESULT_PARAMETER_INVALID; 1995 struct Play_interface *this = (struct Play_interface *) self; 1996 *pMsec = this->mPosition; 1997 // FIXME convert sample units to time units 1998 // SL_TIME_UNKNOWN == this->mPlay.mPosition = SL_TIME_UNKNOWN; 1999 return SL_RESULT_SUCCESS; 2000} 2001 2002static SLresult Play_RegisterCallback(SLPlayItf self, slPlayCallback callback, 2003 void *pContext) 2004{ 2005 struct Play_interface *this = (struct Play_interface *) self; 2006 this->mCallback = callback; 2007 this->mContext = pContext; 2008 return SL_RESULT_SUCCESS; 2009} 2010 2011static SLresult Play_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags) 2012{ 2013 struct Play_interface *this = (struct Play_interface *) self; 2014 this->mEventFlags = eventFlags; 2015 return SL_RESULT_SUCCESS; 2016} 2017 2018static SLresult Play_GetCallbackEventsMask(SLPlayItf self, 2019 SLuint32 *pEventFlags) 2020{ 2021 if (NULL == pEventFlags) 2022 return SL_RESULT_PARAMETER_INVALID; 2023 struct Play_interface *this = (struct Play_interface *) self; 2024 *pEventFlags = this->mEventFlags; 2025 return SL_RESULT_SUCCESS; 2026} 2027 2028static SLresult Play_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec) 2029{ 2030 struct Play_interface *this = (struct Play_interface *) self; 2031 this->mMarkerPosition = mSec; 2032 return SL_RESULT_SUCCESS; 2033} 2034 2035static SLresult Play_ClearMarkerPosition(SLPlayItf self) 2036{ 2037 struct Play_interface *this = (struct Play_interface *) self; 2038 this->mMarkerPosition = 0; 2039 return SL_RESULT_SUCCESS; 2040} 2041 2042static SLresult Play_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec) 2043{ 2044 if (NULL == pMsec) 2045 return SL_RESULT_PARAMETER_INVALID; 2046 struct Play_interface *this = (struct Play_interface *) self; 2047 *pMsec = this->mMarkerPosition; 2048 return SL_RESULT_SUCCESS; 2049} 2050 2051static SLresult Play_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec) 2052{ 2053 struct Play_interface *this = (struct Play_interface *) self; 2054 this->mPositionUpdatePeriod = mSec; 2055 return SL_RESULT_SUCCESS; 2056} 2057 2058static SLresult Play_GetPositionUpdatePeriod(SLPlayItf self, 2059 SLmillisecond *pMsec) 2060{ 2061 if (NULL == pMsec) 2062 return SL_RESULT_PARAMETER_INVALID; 2063 struct Play_interface *this = (struct Play_interface *) self; 2064 *pMsec = this->mPositionUpdatePeriod; 2065 return SL_RESULT_SUCCESS; 2066} 2067 2068/*static*/ const struct SLPlayItf_ Play_PlayItf = { 2069 Play_SetPlayState, 2070 Play_GetPlayState, 2071 Play_GetDuration, 2072 Play_GetPosition, 2073 Play_RegisterCallback, 2074 Play_SetCallbackEventsMask, 2075 Play_GetCallbackEventsMask, 2076 Play_SetMarkerPosition, 2077 Play_ClearMarkerPosition, 2078 Play_GetMarkerPosition, 2079 Play_SetPositionUpdatePeriod, 2080 Play_GetPositionUpdatePeriod 2081}; 2082 2083/* BufferQueue implementation */ 2084 2085static SLresult BufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer, 2086 SLuint32 size) 2087{ 2088 if (NULL == pBuffer) 2089 return SL_RESULT_PARAMETER_INVALID; 2090 struct BufferQueue_interface *this = (struct BufferQueue_interface *) self; 2091 // FIXME race condition need mutex 2092 struct BufferHeader *oldRear = this->mRear; 2093 struct BufferHeader *newRear = oldRear; 2094 if (++newRear == &this->mArray[this->mNumBuffers]) 2095 newRear = this->mArray; 2096 if (newRear == this->mFront) 2097 return SL_RESULT_BUFFER_INSUFFICIENT; 2098 oldRear->mBuffer = pBuffer; 2099 oldRear->mSize = size; 2100 this->mRear = newRear; 2101 ++this->mState.count; 2102 return SL_RESULT_SUCCESS; 2103} 2104 2105static SLresult BufferQueue_Clear(SLBufferQueueItf self) 2106{ 2107 struct BufferQueue_interface *this = (struct BufferQueue_interface *) self; 2108 this->mFront = &this->mArray[0]; 2109 this->mRear = &this->mArray[0]; 2110 return SL_RESULT_SUCCESS; 2111} 2112 2113static SLresult BufferQueue_GetState(SLBufferQueueItf self, 2114 SLBufferQueueState *pState) 2115{ 2116 if (NULL == pState) 2117 return SL_RESULT_PARAMETER_INVALID; 2118 struct BufferQueue_interface *this = (struct BufferQueue_interface *) self; 2119#ifdef __cplusplus 2120 pState->count = this->mState.count; 2121 pState->playIndex = this->mState.playIndex; 2122#else 2123 *pState = this->mState; 2124#endif 2125 return SL_RESULT_SUCCESS; 2126} 2127 2128static SLresult BufferQueue_RegisterCallback(SLBufferQueueItf self, 2129 slBufferQueueCallback callback, void *pContext) 2130{ 2131 struct BufferQueue_interface *this = (struct BufferQueue_interface *) self; 2132 this->mCallback = callback; 2133 this->mContext = pContext; 2134 return SL_RESULT_SUCCESS; 2135} 2136 2137/*static*/ const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf = { 2138 BufferQueue_Enqueue, 2139 BufferQueue_Clear, 2140 BufferQueue_GetState, 2141 BufferQueue_RegisterCallback 2142}; 2143 2144/* Volume implementation */ 2145 2146static SLresult Volume_SetVolumeLevel(SLVolumeItf self, SLmillibel level) 2147{ 2148 // stet despite warning because MIN and MAX might change, and because 2149 // some compilers allow a wider int type to be passed as a parameter 2150 if (!((SL_MILLIBEL_MIN <= level) && (SL_MILLIBEL_MAX >= level))) 2151 return SL_RESULT_PARAMETER_INVALID; 2152 struct Volume_interface *this = (struct Volume_interface *) self; 2153 this->mLevel = level; 2154 return SL_RESULT_SUCCESS; 2155} 2156 2157static SLresult Volume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel) 2158{ 2159 if (NULL == pLevel) 2160 return SL_RESULT_PARAMETER_INVALID; 2161 struct Volume_interface *this = (struct Volume_interface *) self; 2162 *pLevel = this->mLevel; 2163 return SL_RESULT_SUCCESS; 2164} 2165 2166static SLresult Volume_GetMaxVolumeLevel(SLVolumeItf self, 2167 SLmillibel *pMaxLevel) 2168{ 2169 if (NULL == pMaxLevel) 2170 return SL_RESULT_PARAMETER_INVALID; 2171 *pMaxLevel = SL_MILLIBEL_MAX; 2172 return SL_RESULT_SUCCESS; 2173} 2174 2175static SLresult Volume_SetMute(SLVolumeItf self, SLboolean mute) 2176{ 2177 struct Volume_interface *this = (struct Volume_interface *) self; 2178 this->mMute = mute; 2179 return SL_RESULT_SUCCESS; 2180} 2181 2182static SLresult Volume_GetMute(SLVolumeItf self, SLboolean *pMute) 2183{ 2184 if (NULL == pMute) 2185 return SL_RESULT_PARAMETER_INVALID; 2186 struct Volume_interface *this = (struct Volume_interface *) self; 2187 *pMute = this->mMute; 2188 return SL_RESULT_SUCCESS; 2189} 2190 2191static SLresult Volume_EnableStereoPosition(SLVolumeItf self, SLboolean enable) 2192{ 2193 struct Volume_interface *this = (struct Volume_interface *) self; 2194 this->mEnableStereoPosition = enable; 2195 return SL_RESULT_SUCCESS; 2196} 2197 2198static SLresult Volume_IsEnabledStereoPosition(SLVolumeItf self, 2199 SLboolean *pEnable) 2200{ 2201 if (NULL == pEnable) 2202 return SL_RESULT_PARAMETER_INVALID; 2203 struct Volume_interface *this = (struct Volume_interface *) self; 2204 *pEnable = this->mEnableStereoPosition; 2205 return SL_RESULT_SUCCESS; 2206} 2207 2208static SLresult Volume_SetStereoPosition(SLVolumeItf self, 2209 SLpermille stereoPosition) 2210{ 2211 struct Volume_interface *this = (struct Volume_interface *) self; 2212 if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition))) 2213 return SL_RESULT_PARAMETER_INVALID; 2214 this->mStereoPosition = stereoPosition; 2215 return SL_RESULT_SUCCESS; 2216} 2217 2218static SLresult Volume_GetStereoPosition(SLVolumeItf self, 2219 SLpermille *pStereoPosition) 2220{ 2221 if (NULL == pStereoPosition) 2222 return SL_RESULT_PARAMETER_INVALID; 2223 struct Volume_interface *this = (struct Volume_interface *) self; 2224 *pStereoPosition = this->mStereoPosition; 2225 return SL_RESULT_SUCCESS; 2226} 2227 2228/*static*/ const struct SLVolumeItf_ Volume_VolumeItf = { 2229 Volume_SetVolumeLevel, 2230 Volume_GetVolumeLevel, 2231 Volume_GetMaxVolumeLevel, 2232 Volume_SetMute, 2233 Volume_GetMute, 2234 Volume_EnableStereoPosition, 2235 Volume_IsEnabledStereoPosition, 2236 Volume_SetStereoPosition, 2237 Volume_GetStereoPosition 2238}; 2239 2240/* Engine implementation */ 2241 2242static SLresult Engine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, 2243 SLuint32 deviceID, SLuint32 numInterfaces, 2244 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 2245{ 2246 if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID) 2247 return SL_RESULT_PARAMETER_INVALID; 2248 *pDevice = NULL; 2249 unsigned exposedMask; 2250 SLresult result = checkInterfaces(&LEDDevice_class, numInterfaces, 2251 pInterfaceIds, pInterfaceRequired, &exposedMask); 2252 if (SL_RESULT_SUCCESS != result) 2253 return result; 2254 struct LEDDevice_class *this = 2255 (struct LEDDevice_class *) construct(&LEDDevice_class, exposedMask); 2256 if (NULL == this) 2257 return SL_RESULT_MEMORY_FAILURE; 2258 this->mDeviceID = deviceID; 2259 *pDevice = &this->mObject.mItf; 2260 return SL_RESULT_SUCCESS; 2261} 2262 2263static SLresult Engine_CreateVibraDevice(SLEngineItf self, 2264 SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces, 2265 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 2266{ 2267 if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID) 2268 return SL_RESULT_PARAMETER_INVALID; 2269 *pDevice = NULL; 2270 unsigned exposedMask; 2271 SLresult result = checkInterfaces(&VibraDevice_class, numInterfaces, 2272 pInterfaceIds, pInterfaceRequired, &exposedMask); 2273 if (SL_RESULT_SUCCESS != result) 2274 return result; 2275 struct VibraDevice_class *this = 2276 (struct VibraDevice_class *) construct(&VibraDevice_class, exposedMask); 2277 if (NULL == this) 2278 return SL_RESULT_MEMORY_FAILURE; 2279 this->mDeviceID = deviceID; 2280 *pDevice = &this->mObject.mItf; 2281 return SL_RESULT_SUCCESS; 2282} 2283 2284static SLresult Engine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer, 2285 SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, 2286 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 2287{ 2288 if (NULL == pPlayer) 2289 return SL_RESULT_PARAMETER_INVALID; 2290 *pPlayer = NULL; 2291 unsigned exposedMask; 2292 SLresult result = checkInterfaces(&AudioPlayer_class, numInterfaces, 2293 pInterfaceIds, pInterfaceRequired, &exposedMask); 2294 if (SL_RESULT_SUCCESS != result) 2295 return result; 2296 // check the audio source and sinks 2297 // FIXME move this to a separate function: check source, check locator, etc. 2298 if ((NULL == pAudioSrc) || (NULL == (SLuint32 *) pAudioSrc->pLocator) || 2299 (NULL == pAudioSrc->pFormat)) 2300 return SL_RESULT_PARAMETER_INVALID; 2301 SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 2302 SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 2303 SLuint32 numBuffers = 0; 2304 SLDataFormat_PCM *df_pcm = NULL; 2305 struct Track *track = NULL; 2306#ifdef USE_SNDFILE 2307 SLchar *pathname = NULL; 2308#endif // USE_SNDFILE 2309 switch (locatorType) { 2310 case SL_DATALOCATOR_BUFFERQUEUE: 2311 { 2312 SLDataLocator_BufferQueue *dl_bq = 2313 (SLDataLocator_BufferQueue *) pAudioSrc->pLocator; 2314 numBuffers = dl_bq->numBuffers; 2315 if (0 == numBuffers) 2316 return SL_RESULT_PARAMETER_INVALID; 2317 switch (formatType) { 2318 case SL_DATAFORMAT_PCM: 2319 { 2320 df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat; 2321 switch (df_pcm->numChannels) { 2322 case 1: 2323 case 2: 2324 break; 2325 default: 2326 return SL_RESULT_CONTENT_UNSUPPORTED; 2327 } 2328 switch (df_pcm->samplesPerSec) { 2329 case 44100: 2330 break; 2331#if 1 // wrong units for samplesPerSec! 2332 case SL_SAMPLINGRATE_44_1: 2333 break; 2334#endif 2335 // others 2336 default: 2337 return SL_RESULT_CONTENT_UNSUPPORTED; 2338 } 2339 switch (df_pcm->bitsPerSample) { 2340 case SL_PCMSAMPLEFORMAT_FIXED_16: 2341 break; 2342 // others 2343 default: 2344 return SL_RESULT_CONTENT_UNSUPPORTED; 2345 } 2346 switch (df_pcm->containerSize) { 2347 case 16: 2348 break; 2349 // others 2350 default: 2351 return SL_RESULT_CONTENT_UNSUPPORTED; 2352 } 2353 switch (df_pcm->channelMask) { 2354 // needs work 2355 default: 2356 break; 2357 } 2358 switch (df_pcm->endianness) { 2359 case SL_BYTEORDER_LITTLEENDIAN: 2360 break; 2361 // others esp. big and native (new not in spec) 2362 default: 2363 return SL_RESULT_CONTENT_UNSUPPORTED; 2364 } 2365 } 2366 break; 2367 case SL_DATAFORMAT_MIME: 2368 case SL_DATAFORMAT_RESERVED3: 2369 return SL_RESULT_CONTENT_UNSUPPORTED; 2370 default: 2371 return SL_RESULT_PARAMETER_INVALID; 2372 } 2373 } 2374 break; 2375#ifdef USE_SNDFILE 2376 case SL_DATALOCATOR_URI: 2377 { 2378 SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 2379 SLchar *uri = dl_uri->URI; 2380 if (NULL == uri) 2381 return SL_RESULT_PARAMETER_INVALID; 2382 if (strncmp((const char *) uri, "file:///", 8)) 2383 return SL_RESULT_CONTENT_UNSUPPORTED; 2384 pathname = &uri[8]; 2385 switch (formatType) { 2386 case SL_DATAFORMAT_MIME: 2387 { 2388 SLDataFormat_MIME *df_mime = 2389 (SLDataFormat_MIME *) pAudioSrc->pFormat; 2390 SLchar *mimeType = df_mime->mimeType; 2391 if (NULL == mimeType) 2392 return SL_RESULT_PARAMETER_INVALID; 2393 SLuint32 containerType = df_mime->containerType; 2394 if (!strcmp((const char *) mimeType, "audio/x-wav")) 2395 ; 2396 // else if (others) 2397 // ; 2398 else 2399 return SL_RESULT_CONTENT_UNSUPPORTED; 2400 switch (containerType) { 2401 case SL_CONTAINERTYPE_WAV: 2402 break; 2403 // others 2404 default: 2405 return SL_RESULT_CONTENT_UNSUPPORTED; 2406 } 2407 } 2408 break; 2409 default: 2410 return SL_RESULT_CONTENT_UNSUPPORTED; 2411 } 2412 // FIXME magic number, should be configurable 2413 numBuffers = 2; 2414 } 2415 break; 2416#endif // USE_SNDFILE 2417 case SL_DATALOCATOR_ADDRESS: 2418 case SL_DATALOCATOR_IODEVICE: 2419 case SL_DATALOCATOR_OUTPUTMIX: 2420 case SL_DATALOCATOR_RESERVED5: 2421 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 2422 case SL_DATALOCATOR_RESERVED8: 2423 return SL_RESULT_CONTENT_UNSUPPORTED; 2424 default: 2425 return SL_RESULT_PARAMETER_INVALID; 2426 } 2427 // check sink, again this should be a separate function 2428 if (NULL == pAudioSnk || (NULL == (SLuint32 *) pAudioSnk->pLocator)) 2429 return SL_RESULT_PARAMETER_INVALID; 2430 switch (*(SLuint32 *)pAudioSnk->pLocator) { 2431 case SL_DATALOCATOR_OUTPUTMIX: 2432 { 2433 // pAudioSnk->pFormat is ignored 2434 SLDataLocator_OutputMix *dl_outmix = 2435 (SLDataLocator_OutputMix *) pAudioSnk->pLocator; 2436 SLObjectItf outputMix = dl_outmix->outputMix; 2437 // FIXME make this an operation on Object: GetClass 2438 if ((NULL == outputMix) || (&OutputMix_class != 2439 ((struct Object_interface *) outputMix)->mClass)) 2440 return SL_RESULT_PARAMETER_INVALID; 2441 struct OutputMix_interface *om = 2442 &((struct OutputMix_class *) outputMix)->mOutputMix; 2443 // allocate an entry within OutputMix for this track 2444 // FIXME O(n) 2445 unsigned i; 2446 for (i = 0, track = &om->mTracks[0]; i < 32; ++i, ++track) { 2447 if (om->mActiveMask & (1 << i)) 2448 continue; 2449 om->mActiveMask |= 1 << i; 2450 break; 2451 } 2452 if (32 <= i) { 2453 // FIXME Need a better error code for all slots full in output mix 2454 return SL_RESULT_MEMORY_FAILURE; 2455 } 2456 // FIXME replace the above for Android - do not use our own mixer! 2457 } 2458 break; 2459 case SL_DATALOCATOR_BUFFERQUEUE: 2460 case SL_DATALOCATOR_URI: 2461 case SL_DATALOCATOR_ADDRESS: 2462 case SL_DATALOCATOR_IODEVICE: 2463 case SL_DATALOCATOR_RESERVED5: 2464 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 2465 case SL_DATALOCATOR_RESERVED8: 2466 return SL_RESULT_CONTENT_UNSUPPORTED; 2467 default: 2468 return SL_RESULT_PARAMETER_INVALID; 2469 } 2470 // Construct our new instance 2471 struct AudioPlayer_class *this = 2472 (struct AudioPlayer_class *) construct(&AudioPlayer_class, exposedMask); 2473 if (NULL == this) 2474 return SL_RESULT_MEMORY_FAILURE; 2475#if 0 2476 this->mObject.mItf = &AudioPlayer_ObjectItf; // take note! 2477#endif 2478 // FIXME numBuffers is unavailable for URL, must make a default ! 2479 assert(0 < numBuffers); 2480 this->mBufferQueue.mNumBuffers = numBuffers; 2481 // inline allocation of circular mArray, up to a typical max 2482 if (BUFFER_HEADER_TYPICAL >= numBuffers) { 2483 this->mBufferQueue.mArray = this->mBufferQueue.mTypical; 2484 } else { 2485 // FIXME integer overflow possible during multiplication 2486 this->mBufferQueue.mArray = (struct BufferHeader *) 2487 malloc((numBuffers + 1) * sizeof(struct BufferHeader)); 2488 if (NULL == this->mBufferQueue.mArray) { 2489 free(this); 2490 return SL_RESULT_MEMORY_FAILURE; 2491 } 2492 } 2493 this->mBufferQueue.mFront = this->mBufferQueue.mArray; 2494 this->mBufferQueue.mRear = this->mBufferQueue.mArray; 2495#ifdef USE_SNDFILE 2496 this->mSndFile.mPathname = pathname; 2497 this->mSndFile.mIs0 = SL_BOOLEAN_TRUE; 2498#ifndef NDEBUG 2499 this->mSndFile.mSNDFILE = NULL; 2500 this->mSndFile.mRetryBuffer = NULL; 2501 this->mSndFile.mRetrySize = 0; 2502#endif 2503#endif // USE_SNDFILE 2504 // link track to player (NOT for Android!!) 2505 track->mDfPcm = df_pcm; 2506 track->mBufferQueue = &this->mBufferQueue; 2507 track->mPlay = &this->mPlay; 2508 // next 2 fields must be initialized explicitly (not part of this) 2509 track->mReader = NULL; 2510 track->mAvail = 0; 2511 // return the new audio player object 2512 *pPlayer = &this->mObject.mItf; 2513 return SL_RESULT_SUCCESS; 2514} 2515 2516static SLresult Engine_CreateAudioRecorder(SLEngineItf self, 2517 SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, 2518 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2519 const SLboolean *pInterfaceRequired) 2520{ 2521 if (NULL == pRecorder) 2522 return SL_RESULT_PARAMETER_INVALID; 2523 *pRecorder = NULL; 2524 unsigned exposedMask; 2525 SLresult result = checkInterfaces(&AudioRecorder_class, numInterfaces, 2526 pInterfaceIds, pInterfaceRequired, &exposedMask); 2527 if (SL_RESULT_SUCCESS != result) 2528 return result; 2529 return SL_RESULT_SUCCESS; 2530} 2531 2532static SLresult Engine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 2533 SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 2534 SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 2535 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 2536{ 2537 if (NULL == pPlayer) 2538 return SL_RESULT_PARAMETER_INVALID; 2539 *pPlayer = NULL; 2540 unsigned exposedMask; 2541 SLresult result = checkInterfaces(&MidiPlayer_class, numInterfaces, 2542 pInterfaceIds, pInterfaceRequired, &exposedMask); 2543 if (SL_RESULT_SUCCESS != result) 2544 return result; 2545 if (NULL == pMIDISrc || NULL == pAudioOutput) 2546 return SL_RESULT_PARAMETER_INVALID; 2547 struct MidiPlayer_class *this = 2548 (struct MidiPlayer_class *) construct(&MidiPlayer_class, exposedMask); 2549 if (NULL == this) 2550 return SL_RESULT_MEMORY_FAILURE; 2551 // return the new MIDI player object 2552 *pPlayer = &this->mObject.mItf; 2553 return SL_RESULT_SUCCESS; 2554} 2555 2556static SLresult Engine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 2557 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2558 const SLboolean *pInterfaceRequired) 2559{ 2560 if (NULL == pListener) 2561 return SL_RESULT_PARAMETER_INVALID; 2562 *pListener = NULL; 2563 unsigned exposedMask; 2564 SLresult result = checkInterfaces(&Listener_class, numInterfaces, 2565 pInterfaceIds, pInterfaceRequired, &exposedMask); 2566 if (SL_RESULT_SUCCESS != result) 2567 return result; 2568 return SL_RESULT_FEATURE_UNSUPPORTED; 2569} 2570 2571static SLresult Engine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, 2572 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2573 const SLboolean *pInterfaceRequired) 2574{ 2575 if (NULL == pGroup) 2576 return SL_RESULT_PARAMETER_INVALID; 2577 *pGroup = NULL; 2578 unsigned exposedMask; 2579 SLresult result = checkInterfaces(&_3DGroup_class, numInterfaces, 2580 pInterfaceIds, pInterfaceRequired, &exposedMask); 2581 if (SL_RESULT_SUCCESS != result) 2582 return result; 2583 return SL_RESULT_FEATURE_UNSUPPORTED; 2584} 2585 2586static SLresult Engine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, 2587 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2588 const SLboolean *pInterfaceRequired) 2589{ 2590 if (NULL == pMix) 2591 return SL_RESULT_PARAMETER_INVALID; 2592 *pMix = NULL; 2593 unsigned exposedMask; 2594 SLresult result = checkInterfaces(&OutputMix_class, numInterfaces, 2595 pInterfaceIds, pInterfaceRequired, &exposedMask); 2596 if (SL_RESULT_SUCCESS != result) 2597 return result; 2598 struct OutputMix_class *this = 2599 (struct OutputMix_class *) construct(&OutputMix_class, exposedMask); 2600 if (NULL == this) 2601 return SL_RESULT_MEMORY_FAILURE; 2602 *pMix = &this->mObject.mItf; 2603 return SL_RESULT_SUCCESS; 2604} 2605 2606static SLresult Engine_CreateMetadataExtractor(SLEngineItf self, 2607 SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource, 2608 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2609 const SLboolean *pInterfaceRequired) 2610{ 2611 if (NULL == pMetadataExtractor) 2612 return SL_RESULT_PARAMETER_INVALID; 2613 *pMetadataExtractor = NULL; 2614 unsigned exposedMask; 2615 SLresult result = checkInterfaces(&MetadataExtractor_class, numInterfaces, 2616 pInterfaceIds, pInterfaceRequired, &exposedMask); 2617 if (SL_RESULT_SUCCESS != result) 2618 return result; 2619 struct MetadataExtractor_class *this = (struct MetadataExtractor_class *) 2620 construct(&MetadataExtractor_class, exposedMask); 2621 if (NULL == this) 2622 return SL_RESULT_MEMORY_FAILURE; 2623 *pMetadataExtractor = &this->mObject.mItf; 2624 return SL_RESULT_SUCCESS; 2625} 2626 2627static SLresult Engine_CreateExtensionObject(SLEngineItf self, 2628 SLObjectItf *pObject, void *pParameters, SLuint32 objectID, 2629 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 2630 const SLboolean *pInterfaceRequired) 2631{ 2632 if (NULL == pObject) 2633 return SL_RESULT_PARAMETER_INVALID; 2634 *pObject = NULL; 2635 return SL_RESULT_FEATURE_UNSUPPORTED; 2636} 2637 2638static SLresult Engine_QueryNumSupportedInterfaces(SLEngineItf self, 2639 SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 2640{ 2641 if (NULL == pNumSupportedInterfaces) 2642 return SL_RESULT_PARAMETER_INVALID; 2643 const struct class_ *class__ = objectIDtoClass(objectID); 2644 if (NULL == class__) 2645 return SL_RESULT_FEATURE_UNSUPPORTED; 2646 *pNumSupportedInterfaces = class__->mInterfaceCount; 2647 return SL_RESULT_SUCCESS; 2648} 2649 2650static SLresult Engine_QuerySupportedInterfaces(SLEngineItf self, 2651 SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 2652{ 2653 return SL_RESULT_SUCCESS; 2654} 2655 2656static SLresult Engine_QueryNumSupportedExtensions(SLEngineItf self, 2657 SLuint32 *pNumExtensions) 2658{ 2659 if (NULL == pNumExtensions) 2660 return SL_RESULT_PARAMETER_INVALID; 2661 *pNumExtensions = 0; 2662 return SL_RESULT_SUCCESS; 2663} 2664 2665static SLresult Engine_QuerySupportedExtension(SLEngineItf self, 2666 SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 2667{ 2668 // any index >= 0 will be >= number of supported extensions 2669 return SL_RESULT_PARAMETER_INVALID; 2670} 2671 2672static SLresult Engine_IsExtensionSupported(SLEngineItf self, 2673 const SLchar *pExtensionName, SLboolean *pSupported) 2674{ 2675 if (NULL == pExtensionName || NULL == pSupported) 2676 return SL_RESULT_PARAMETER_INVALID; 2677 *pSupported = SL_BOOLEAN_FALSE; 2678 return SL_RESULT_SUCCESS; 2679} 2680 2681/*static*/ const struct SLEngineItf_ Engine_EngineItf = { 2682 Engine_CreateLEDDevice, 2683 Engine_CreateVibraDevice, 2684 Engine_CreateAudioPlayer, 2685 Engine_CreateAudioRecorder, 2686 Engine_CreateMidiPlayer, 2687 Engine_CreateListener, 2688 Engine_Create3DGroup, 2689 Engine_CreateOutputMix, 2690 Engine_CreateMetadataExtractor, 2691 Engine_CreateExtensionObject, 2692 Engine_QueryNumSupportedInterfaces, 2693 Engine_QuerySupportedInterfaces, 2694 Engine_QueryNumSupportedExtensions, 2695 Engine_QuerySupportedExtension, 2696 Engine_IsExtensionSupported 2697}; 2698 2699/* AudioIODeviceCapabilities implementation */ 2700 2701static SLresult AudioIODeviceCapabilities_GetAvailableAudioInputs( 2702 SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumInputs, 2703 SLuint32 *pInputDeviceIDs) 2704{ 2705 return SL_RESULT_SUCCESS; 2706} 2707 2708static SLresult AudioIODeviceCapabilities_QueryAudioInputCapabilities( 2709 SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, 2710 SLAudioInputDescriptor *pDescriptor) 2711{ 2712 return SL_RESULT_SUCCESS; 2713} 2714 2715static SLresult 2716 AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback( 2717 SLAudioIODeviceCapabilitiesItf self, 2718 slAvailableAudioInputsChangedCallback callback, void *pContext) 2719{ 2720 return SL_RESULT_SUCCESS; 2721} 2722 2723static SLresult AudioIODeviceCapabilities_GetAvailableAudioOutputs( 2724 SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumOutputs, 2725 SLuint32 *pOutputDeviceIDs) 2726{ 2727 if (NULL == pNumOutputs) 2728 return SL_RESULT_PARAMETER_INVALID; 2729 if (NULL != pOutputDeviceIDs) { 2730 // FIXME should be OEM-configurable 2731 if (2 > *pNumOutputs) 2732 return SL_RESULT_BUFFER_INSUFFICIENT; 2733 pOutputDeviceIDs[0] = DEVICE_ID_HEADSET; 2734 pOutputDeviceIDs[1] = DEVICE_ID_HANDSFREE; 2735 } 2736 *pNumOutputs = 2; 2737 return SL_RESULT_SUCCESS; 2738} 2739 2740static SLresult AudioIODeviceCapabilities_QueryAudioOutputCapabilities( 2741 SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, 2742 SLAudioOutputDescriptor *pDescriptor) 2743{ 2744 if (NULL == pDescriptor) 2745 return SL_RESULT_PARAMETER_INVALID; 2746 switch (deviceID) { 2747 // FIXME should be OEM-configurable 2748 case DEVICE_ID_HEADSET: 2749 *pDescriptor = AudioOutputDescriptor_headset; 2750 break; 2751 case DEVICE_ID_HANDSFREE: 2752 *pDescriptor = AudioOutputDescriptor_handsfree; 2753 break; 2754 default: 2755 return SL_RESULT_IO_ERROR; 2756 } 2757 return SL_RESULT_SUCCESS; 2758} 2759 2760static SLresult 2761 AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback( 2762 SLAudioIODeviceCapabilitiesItf self, 2763 slAvailableAudioOutputsChangedCallback callback, void *pContext) 2764{ 2765 return SL_RESULT_SUCCESS; 2766} 2767 2768static SLresult 2769 AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback( 2770 SLAudioIODeviceCapabilitiesItf self, 2771 slDefaultDeviceIDMapChangedCallback callback, void *pContext) 2772{ 2773 return SL_RESULT_SUCCESS; 2774} 2775 2776static SLresult AudioIODeviceCapabilities_GetAssociatedAudioInputs( 2777 SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, 2778 SLint32 *pNumAudioInputs, SLuint32 *pAudioInputDeviceIDs) 2779{ 2780 return SL_RESULT_SUCCESS; 2781} 2782 2783static SLresult AudioIODeviceCapabilities_GetAssociatedAudioOutputs( 2784 SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, 2785 SLint32 *pNumAudioOutputs, SLuint32 *pAudioOutputDeviceIDs) 2786{ 2787 return SL_RESULT_SUCCESS; 2788} 2789 2790static SLresult AudioIODeviceCapabilities_GetDefaultAudioDevices( 2791 SLAudioIODeviceCapabilitiesItf self, SLuint32 defaultDeviceID, 2792 SLint32 *pNumAudioDevices, SLuint32 *pAudioDeviceIDs) 2793{ 2794 return SL_RESULT_SUCCESS; 2795} 2796 2797static SLresult AudioIODeviceCapabilities_QuerySampleFormatsSupported( 2798 SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, 2799 SLmilliHertz samplingRate, SLint32 *pSampleFormats, 2800 SLint32 *pNumOfSampleFormats) 2801{ 2802 return SL_RESULT_SUCCESS; 2803} 2804 2805/*static*/ const struct SLAudioIODeviceCapabilitiesItf_ 2806 AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf = { 2807 AudioIODeviceCapabilities_GetAvailableAudioInputs, 2808 AudioIODeviceCapabilities_QueryAudioInputCapabilities, 2809 AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback, 2810 AudioIODeviceCapabilities_GetAvailableAudioOutputs, 2811 AudioIODeviceCapabilities_QueryAudioOutputCapabilities, 2812 AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback, 2813 AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback, 2814 AudioIODeviceCapabilities_GetAssociatedAudioInputs, 2815 AudioIODeviceCapabilities_GetAssociatedAudioOutputs, 2816 AudioIODeviceCapabilities_GetDefaultAudioDevices, 2817 AudioIODeviceCapabilities_QuerySampleFormatsSupported 2818}; 2819 2820/* OutputMix implementation */ 2821 2822static SLresult OutputMix_GetDestinationOutputDeviceIDs(SLOutputMixItf self, 2823 SLint32 *pNumDevices, SLuint32 *pDeviceIDs) 2824{ 2825 return SL_RESULT_SUCCESS; 2826} 2827 2828static SLresult OutputMix_RegisterDeviceChangeCallback(SLOutputMixItf self, 2829 slMixDeviceChangeCallback callback, void *pContext) 2830{ 2831 return SL_RESULT_SUCCESS; 2832} 2833 2834static SLresult OutputMix_ReRoute(SLOutputMixItf self, SLint32 numOutputDevices, 2835 SLuint32 *pOutputDeviceIDs) 2836{ 2837 return SL_RESULT_SUCCESS; 2838} 2839 2840/*static*/ const struct SLOutputMixItf_ OutputMix_OutputMixItf = { 2841 OutputMix_GetDestinationOutputDeviceIDs, 2842 OutputMix_RegisterDeviceChangeCallback, 2843 OutputMix_ReRoute 2844}; 2845 2846/* Seek implementation */ 2847 2848static SLresult Seek_SetPosition(SLSeekItf self, SLmillisecond pos, 2849 SLuint32 seekMode) 2850{ 2851 switch (seekMode) { 2852 case SL_SEEKMODE_FAST: 2853 case SL_SEEKMODE_ACCURATE: 2854 break; 2855 default: 2856 return SL_RESULT_PARAMETER_INVALID; 2857 } 2858 struct Seek_interface *this = (struct Seek_interface *) self; 2859 this->mPos = pos; 2860 return SL_RESULT_SUCCESS; 2861} 2862 2863static SLresult Seek_SetLoop(SLSeekItf self, SLboolean loopEnable, 2864 SLmillisecond startPos, SLmillisecond endPos) 2865{ 2866 struct Seek_interface *this = (struct Seek_interface *) self; 2867 this->mLoopEnabled = loopEnable; 2868 this->mStartPos = startPos; 2869 this->mEndPos = endPos; 2870 return SL_RESULT_SUCCESS; 2871} 2872 2873static SLresult Seek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled, 2874 SLmillisecond *pStartPos, SLmillisecond *pEndPos) 2875{ 2876 if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos) 2877 return SL_RESULT_PARAMETER_INVALID; 2878 struct Seek_interface *this = (struct Seek_interface *) self; 2879 *pLoopEnabled = this->mLoopEnabled; 2880 *pStartPos = this->mStartPos; 2881 *pEndPos = this->mEndPos; 2882 return SL_RESULT_SUCCESS; 2883} 2884 2885/*static*/ const struct SLSeekItf_ Seek_SeekItf = { 2886 Seek_SetPosition, 2887 Seek_SetLoop, 2888 Seek_GetLoop 2889}; 2890 2891/* 3DCommit implementation */ 2892 2893static SLresult _3DCommit_Commit(SL3DCommitItf self) 2894{ 2895 return SL_RESULT_SUCCESS; 2896} 2897 2898static SLresult _3DCommit_SetDeferred(SL3DCommitItf self, SLboolean deferred) 2899{ 2900 struct _3DCommit_interface *this = (struct _3DCommit_interface *) self; 2901 this->mDeferred = deferred; 2902 return SL_RESULT_SUCCESS; 2903} 2904 2905/*static*/ const struct SL3DCommitItf_ _3DCommit_3DCommitItf = { 2906 _3DCommit_Commit, 2907 _3DCommit_SetDeferred 2908}; 2909 2910/* 3DDoppler implementation */ 2911 2912static SLresult _3DDoppler_SetVelocityCartesian(SL3DDopplerItf self, 2913 const SLVec3D *pVelocity) 2914{ 2915 if (NULL == pVelocity) 2916 return SL_RESULT_PARAMETER_INVALID; 2917 struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self; 2918 this->mVelocity.mCartesian = *pVelocity; 2919 return SL_RESULT_SUCCESS; 2920} 2921 2922static SLresult _3DDoppler_SetVelocitySpherical(SL3DDopplerItf self, 2923 SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter speed) 2924{ 2925 struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self; 2926 this->mVelocity.mSpherical.mAzimuth = azimuth; 2927 this->mVelocity.mSpherical.mElevation = elevation; 2928 this->mVelocity.mSpherical.mSpeed = speed; 2929 return SL_RESULT_SUCCESS; 2930} 2931 2932static SLresult _3DDoppler_GetVelocityCartesian(SL3DDopplerItf self, 2933 SLVec3D *pVelocity) 2934{ 2935 if (NULL == pVelocity) 2936 return SL_RESULT_PARAMETER_INVALID; 2937 struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self; 2938 *pVelocity = this->mVelocity.mCartesian; 2939 return SL_RESULT_SUCCESS; 2940} 2941 2942static SLresult _3DDoppler_SetDopplerFactor(SL3DDopplerItf self, 2943 SLpermille dopplerFactor) 2944{ 2945 struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self; 2946 this->mDopplerFactor = dopplerFactor; 2947 return SL_RESULT_SUCCESS; 2948} 2949 2950static SLresult _3DDoppler_GetDopplerFactor(SL3DDopplerItf self, 2951 SLpermille *pDopplerFactor) 2952{ 2953 if (NULL == pDopplerFactor) 2954 return SL_RESULT_PARAMETER_INVALID; 2955 struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self; 2956 *pDopplerFactor = this->mDopplerFactor; 2957 return SL_RESULT_SUCCESS; 2958} 2959 2960/*static*/ const struct SL3DDopplerItf_ _3DDoppler_3DDopplerItf = { 2961 _3DDoppler_SetVelocityCartesian, 2962 _3DDoppler_SetVelocitySpherical, 2963 _3DDoppler_GetVelocityCartesian, 2964 _3DDoppler_SetDopplerFactor, 2965 _3DDoppler_GetDopplerFactor 2966}; 2967 2968/* 3DLocation implementation */ 2969 2970static SLresult _3DLocation_SetLocationCartesian(SL3DLocationItf self, 2971 const SLVec3D *pLocation) 2972{ 2973 if (NULL == pLocation) 2974 return SL_RESULT_PARAMETER_INVALID; 2975 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 2976 this->mLocation.mCartesian = *pLocation; 2977 return SL_RESULT_SUCCESS; 2978} 2979 2980static SLresult _3DLocation_SetLocationSpherical(SL3DLocationItf self, 2981 SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance) 2982{ 2983 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 2984 this->mLocation.mSpherical.mAzimuth = azimuth; 2985 this->mLocation.mSpherical.mElevation = elevation; 2986 this->mLocation.mSpherical.mDistance = distance; 2987 return SL_RESULT_SUCCESS; 2988} 2989 2990static SLresult _3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement) 2991{ 2992 if (NULL == pMovement) 2993 return SL_RESULT_PARAMETER_INVALID; 2994 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 2995 this->mLocation.mCartesian.x += pMovement->x; 2996 this->mLocation.mCartesian.y += pMovement->y; 2997 this->mLocation.mCartesian.z += pMovement->z; 2998 return SL_RESULT_SUCCESS; 2999} 3000 3001static SLresult _3DLocation_GetLocationCartesian(SL3DLocationItf self, 3002 SLVec3D *pLocation) 3003{ 3004 if (NULL == pLocation) 3005 return SL_RESULT_PARAMETER_INVALID; 3006 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 3007 *pLocation = this->mLocation.mCartesian; 3008 return SL_RESULT_SUCCESS; 3009} 3010 3011static SLresult _3DLocation_SetOrientationVectors(SL3DLocationItf self, 3012 const SLVec3D *pFront, const SLVec3D *pAbove) 3013{ 3014 if (NULL == pFront || NULL == pAbove) 3015 return SL_RESULT_PARAMETER_INVALID; 3016 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 3017 this->mFront = *pFront; 3018 this->mAbove = *pAbove; 3019 return SL_RESULT_SUCCESS; 3020} 3021 3022static SLresult _3DLocation_SetOrientationAngles(SL3DLocationItf self, 3023 SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll) 3024{ 3025 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 3026 this->mHeading = heading; 3027 this->mPitch = pitch; 3028 this->mRoll = roll; 3029 return SL_RESULT_SUCCESS; 3030} 3031 3032static SLresult _3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta, 3033 const SLVec3D *pAxis) 3034{ 3035 if (NULL == pAxis) 3036 return SL_RESULT_PARAMETER_INVALID; 3037 return SL_RESULT_SUCCESS; 3038} 3039 3040static SLresult _3DLocation_GetOrientationVectors(SL3DLocationItf self, 3041 SLVec3D *pFront, SLVec3D *pUp) 3042{ 3043 if (NULL == pFront || NULL == pUp) 3044 return SL_RESULT_PARAMETER_INVALID; 3045 struct _3DLocation_interface *this = (struct _3DLocation_interface *) self; 3046 *pFront = this->mFront; 3047 *pUp = this->mUp; 3048 return SL_RESULT_SUCCESS; 3049} 3050 3051/*static*/ const struct SL3DLocationItf_ _3DLocation_3DLocationItf = { 3052 _3DLocation_SetLocationCartesian, 3053 _3DLocation_SetLocationSpherical, 3054 _3DLocation_Move, 3055 _3DLocation_GetLocationCartesian, 3056 _3DLocation_SetOrientationVectors, 3057 _3DLocation_SetOrientationAngles, 3058 _3DLocation_Rotate, 3059 _3DLocation_GetOrientationVectors 3060}; 3061 3062/* AudioDecoderCapabilities implementation */ 3063 3064// FIXME should build this table from Caps table below 3065static const SLuint32 Our_Decoder_IDs[] = { 3066 SL_AUDIOCODEC_PCM, 3067 SL_AUDIOCODEC_MP3, 3068 SL_AUDIOCODEC_AMR, 3069 SL_AUDIOCODEC_AMRWB, 3070 SL_AUDIOCODEC_AMRWBPLUS, 3071 SL_AUDIOCODEC_AAC, 3072 SL_AUDIOCODEC_WMA, 3073 SL_AUDIOCODEC_REAL, 3074// FIXME not in 1.0.1 header file 3075#define SL_AUDIOCODEC_VORBIS ((SLuint32) 0x00000009) 3076 SL_AUDIOCODEC_VORBIS 3077}; 3078#define MAX_DECODERS (sizeof(Our_Decoder_IDs) / sizeof(Our_Decoder_IDs[0])) 3079 3080static SLresult AudioDecoderCapabilities_GetAudioDecoders( 3081 SLAudioDecoderCapabilitiesItf self, SLuint32 *pNumDecoders, 3082 SLuint32 *pDecoderIds) 3083{ 3084 if (NULL == pNumDecoders) 3085 return SL_RESULT_PARAMETER_INVALID; 3086 if (NULL == pDecoderIds) 3087 *pNumDecoders = MAX_DECODERS; 3088 else { 3089 SLuint32 numDecoders = *pNumDecoders; 3090 if (MAX_DECODERS < numDecoders) { 3091 numDecoders = MAX_DECODERS; 3092 *pNumDecoders = MAX_DECODERS; 3093 } 3094 memcpy(pDecoderIds, Our_Decoder_IDs, numDecoders * sizeof(SLuint32)); 3095 } 3096 return SL_RESULT_SUCCESS; 3097} 3098 3099static const SLmilliHertz Sample_Rates_PCM[] = { 3100 SL_SAMPLINGRATE_8, 3101 SL_SAMPLINGRATE_11_025, 3102 SL_SAMPLINGRATE_12, 3103 SL_SAMPLINGRATE_16, 3104 SL_SAMPLINGRATE_22_05, 3105 SL_SAMPLINGRATE_24, 3106 SL_SAMPLINGRATE_32, 3107 SL_SAMPLINGRATE_44_1, 3108 SL_SAMPLINGRATE_48 3109}; 3110 3111static const SLAudioCodecDescriptor Caps_PCM[] = { 3112 { 3113 2, // maxChannels 3114 8, // minBitsPerSample 3115 16, // maxBitsPerSample 3116 SL_SAMPLINGRATE_8, // minSampleRate 3117 SL_SAMPLINGRATE_48, // maxSampleRate 3118 SL_BOOLEAN_FALSE, // isFreqRangeContinuous 3119 (SLmilliHertz *) Sample_Rates_PCM, 3120 // pSampleRatesSupported; 3121 sizeof(Sample_Rates_PCM)/sizeof(Sample_Rates_PCM[0]), 3122 // numSampleRatesSupported 3123 1, // minBitRate 3124 ~0, // maxBitRate 3125 SL_BOOLEAN_TRUE, // isBitrateRangeContinuous 3126 NULL, // pBitratesSupported 3127 0, // numBitratesSupported 3128 SL_AUDIOPROFILE_PCM, // profileSetting 3129 0 // modeSetting 3130 } 3131}; 3132 3133static const struct AudioDecoderCapabilities { 3134 SLuint32 mDecoderID; 3135 SLuint32 mNumCapabilities; 3136 const SLAudioCodecDescriptor *mDescriptors; 3137} Our_Decoder_Capabilities[] = { 3138#define ENTRY(x) \ 3139 {SL_AUDIOCODEC_##x, sizeof(Caps_##x)/sizeof(Caps_##x[0]), Caps_##x} 3140 ENTRY(PCM) 3141#if 0 3142 ENTRY(MP3), 3143 ENTRY(AMR), 3144 ENTRY(AMRWB), 3145 ENTRY(AMRWBPLUS), 3146 ENTRY(AAC), 3147 ENTRY(WMA), 3148 ENTRY(REAL), 3149 ENTRY(VORBIS) 3150#endif 3151}; 3152 3153static SLresult AudioDecoderCapabilities_GetAudioDecoderCapabilities( 3154 SLAudioDecoderCapabilitiesItf self, SLuint32 decoderId, SLuint32 *pIndex, 3155 SLAudioCodecDescriptor *pDescriptor) 3156{ 3157 return SL_RESULT_SUCCESS; 3158} 3159 3160/*static*/ const struct SLAudioDecoderCapabilitiesItf_ 3161 AudioDecoderCapabilities_AudioDecoderCapabilitiesItf = { 3162 AudioDecoderCapabilities_GetAudioDecoders, 3163 AudioDecoderCapabilities_GetAudioDecoderCapabilities 3164}; 3165 3166/* AudioEncoder implementation */ 3167 3168static SLresult AudioEncoder_SetEncoderSettings(SLAudioEncoderItf self, 3169 SLAudioEncoderSettings *pSettings) 3170{ 3171 if (NULL == pSettings) 3172 return SL_RESULT_PARAMETER_INVALID; 3173 struct AudioEncoder_interface *this = 3174 (struct AudioEncoder_interface *) self; 3175 this->mSettings = *pSettings; 3176 return SL_RESULT_SUCCESS; 3177} 3178 3179static SLresult AudioEncoder_GetEncoderSettings(SLAudioEncoderItf self, 3180 SLAudioEncoderSettings *pSettings) 3181{ 3182 if (NULL == pSettings) 3183 return SL_RESULT_PARAMETER_INVALID; 3184 struct AudioEncoder_interface *this = 3185 (struct AudioEncoder_interface *) self; 3186 *pSettings = this->mSettings; 3187 return SL_RESULT_SUCCESS; 3188} 3189 3190/*static*/ const struct SLAudioEncoderItf_ AudioEncoder_AudioEncoderItf = { 3191 AudioEncoder_SetEncoderSettings, 3192 AudioEncoder_GetEncoderSettings 3193}; 3194 3195/* AudioEncoderCapabilities implementation */ 3196 3197static SLresult AudioEncoderCapabilities_GetAudioEncoders( 3198 SLAudioEncoderCapabilitiesItf self, SLuint32 *pNumEncoders, 3199 SLuint32 *pEncoderIds) 3200{ 3201 return SL_RESULT_SUCCESS; 3202} 3203 3204static SLresult AudioEncoderCapabilities_GetAudioEncoderCapabilities( 3205 SLAudioEncoderCapabilitiesItf self, SLuint32 encoderId, SLuint32 *pIndex, 3206 SLAudioCodecDescriptor *pDescriptor) 3207{ 3208 return SL_RESULT_SUCCESS; 3209} 3210 3211/*static*/ const struct SLAudioEncoderCapabilitiesItf_ 3212 AudioEncoderCapabilities_AudioEncoderCapabilitiesItf = { 3213 AudioEncoderCapabilities_GetAudioEncoders, 3214 AudioEncoderCapabilities_GetAudioEncoderCapabilities 3215}; 3216 3217/* DeviceVolume implementation */ 3218 3219static SLresult DeviceVolume_GetVolumeScale(SLDeviceVolumeItf self, 3220 SLuint32 deviceID, SLint32 *pMinValue, SLint32 *pMaxValue, 3221 SLboolean *pIsMillibelScale) 3222{ 3223 if (NULL != pMinValue) 3224 *pMinValue = 0; 3225 if (NULL != pMaxValue) 3226 *pMaxValue = 10; 3227 if (NULL != pIsMillibelScale) 3228 *pIsMillibelScale = SL_BOOLEAN_FALSE; 3229 return SL_RESULT_SUCCESS; 3230} 3231 3232static SLresult DeviceVolume_SetVolume(SLDeviceVolumeItf self, 3233 SLuint32 deviceID, SLint32 volume) 3234{ 3235 struct DeviceVolume_interface *this = 3236 (struct DeviceVolume_interface *) self; 3237 this->mVolume = volume; 3238 return SL_RESULT_SUCCESS; 3239} 3240 3241static SLresult DeviceVolume_GetVolume(SLDeviceVolumeItf self, 3242 SLuint32 deviceID, SLint32 *pVolume) 3243{ 3244 if (NULL == pVolume) 3245 return SL_RESULT_PARAMETER_INVALID; 3246 struct DeviceVolume_interface *this = 3247 (struct DeviceVolume_interface *) self; 3248 *pVolume = this->mVolume; 3249 return SL_RESULT_SUCCESS; 3250} 3251 3252/*static*/ const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf = { 3253 DeviceVolume_GetVolumeScale, 3254 DeviceVolume_SetVolume, 3255 DeviceVolume_GetVolume 3256}; 3257 3258/* DynamicSource implementation */ 3259 3260static SLresult DynamicSource_SetSource(SLDynamicSourceItf self, 3261 SLDataSource *pDataSource) 3262{ 3263 return SL_RESULT_SUCCESS; 3264} 3265 3266/*static*/ const struct SLDynamicSourceItf_ DynamicSource_DynamicSourceItf = { 3267 DynamicSource_SetSource 3268}; 3269 3270/* EffectSend implementation */ 3271 3272static SLresult EffectSend_EnableEffectSend(SLEffectSendItf self, 3273 const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel) 3274{ 3275 return SL_RESULT_SUCCESS; 3276} 3277 3278static SLresult EffectSend_IsEnabled(SLEffectSendItf self, 3279 const void *pAuxEffect, SLboolean *pEnable) 3280{ 3281 return SL_RESULT_SUCCESS; 3282} 3283 3284static SLresult EffectSend_SetDirectLevel(SLEffectSendItf self, 3285 SLmillibel directLevel) 3286{ 3287 return SL_RESULT_SUCCESS; 3288} 3289 3290static SLresult EffectSend_GetDirectLevel(SLEffectSendItf self, 3291 SLmillibel *pDirectLevel) 3292{ 3293 return SL_RESULT_SUCCESS; 3294} 3295 3296static SLresult EffectSend_SetSendLevel(SLEffectSendItf self, 3297 const void *pAuxEffect, SLmillibel sendLevel) 3298{ 3299 return SL_RESULT_SUCCESS; 3300} 3301 3302static SLresult EffectSend_GetSendLevel(SLEffectSendItf self, 3303 const void *pAuxEffect, SLmillibel *pSendLevel) 3304{ 3305 return SL_RESULT_SUCCESS; 3306} 3307 3308/*static*/ const struct SLEffectSendItf_ EffectSend_EffectSendItf = { 3309 EffectSend_EnableEffectSend, 3310 EffectSend_IsEnabled, 3311 EffectSend_SetDirectLevel, 3312 EffectSend_GetDirectLevel, 3313 EffectSend_SetSendLevel, 3314 EffectSend_GetSendLevel 3315}; 3316 3317/* EngineCapabilities implementation */ 3318 3319static SLresult EngineCapabilities_QuerySupportedProfiles( 3320 SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported) 3321{ 3322 if (NULL == pProfilesSupported) 3323 return SL_RESULT_PARAMETER_INVALID; 3324 // FIXME This is pessimistic as it omits the unofficial driver profile 3325 // SL_PROFILES_PHONE | SL_PROFILES_MUSIC | SL_PROFILES_GAME 3326 *pProfilesSupported = 0; 3327 return SL_RESULT_SUCCESS; 3328} 3329 3330static SLresult EngineCapabilities_QueryAvailableVoices( 3331 SLEngineCapabilitiesItf self, SLuint16 voiceType, SLint16 *pNumMaxVoices, 3332 SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices) 3333{ 3334 switch (voiceType) { 3335 case SL_VOICETYPE_2D_AUDIO: 3336 case SL_VOICETYPE_MIDI: 3337 case SL_VOICETYPE_3D_AUDIO: 3338 case SL_VOICETYPE_3D_MIDIOUTPUT: 3339 break; 3340 default: 3341 return SL_RESULT_PARAMETER_INVALID; 3342 } 3343 if (NULL != pNumMaxVoices) 3344 *pNumMaxVoices = 0; 3345 if (NULL != pIsAbsoluteMax) 3346 *pIsAbsoluteMax = SL_BOOLEAN_TRUE; 3347 if (NULL != pNumFreeVoices) 3348 *pNumFreeVoices = 0; 3349 return SL_RESULT_SUCCESS; 3350} 3351 3352static SLresult EngineCapabilities_QueryNumberOfMIDISynthesizers( 3353 SLEngineCapabilitiesItf self, SLint16 *pNum) 3354{ 3355 if (NULL == pNum) 3356 return SL_RESULT_PARAMETER_INVALID; 3357 *pNum = 0; 3358 return SL_RESULT_SUCCESS; 3359} 3360 3361static SLresult EngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self, 3362 SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep) 3363{ 3364 if (!(NULL != pMajor && NULL != pMinor && NULL != pStep)) 3365 return SL_RESULT_PARAMETER_INVALID; 3366 *pMajor = 1; 3367 *pMinor = 0; 3368 *pStep = 1; 3369 return SL_RESULT_SUCCESS; 3370} 3371 3372static SLresult EngineCapabilities_QueryLEDCapabilities( 3373 SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pLEDDeviceID, 3374 SLLEDDescriptor *pDescriptor) 3375{ 3376 return SL_RESULT_SUCCESS; 3377} 3378 3379static SLresult EngineCapabilities_QueryVibraCapabilities( 3380 SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pVibraDeviceID, 3381 SLVibraDescriptor *pDescriptor) 3382{ 3383 return SL_RESULT_SUCCESS; 3384} 3385 3386static SLresult EngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self, 3387 SLboolean *pIsThreadSafe) 3388{ 3389 if (NULL == pIsThreadSafe) 3390 return SL_RESULT_PARAMETER_INVALID; 3391 // FIXME For now 3392 *pIsThreadSafe = SL_BOOLEAN_FALSE; 3393 return SL_RESULT_SUCCESS; 3394} 3395 3396/*static*/ const struct SLEngineCapabilitiesItf_ 3397 EngineCapabilities_EngineCapabilitiesItf = { 3398 EngineCapabilities_QuerySupportedProfiles, 3399 EngineCapabilities_QueryAvailableVoices, 3400 EngineCapabilities_QueryNumberOfMIDISynthesizers, 3401 EngineCapabilities_QueryAPIVersion, 3402 EngineCapabilities_QueryLEDCapabilities, 3403 EngineCapabilities_QueryVibraCapabilities, 3404 EngineCapabilities_IsThreadSafe 3405}; 3406 3407/* LEDArray implementation */ 3408 3409static SLresult LEDArray_ActivateLEDArray(SLLEDArrayItf self, 3410 SLuint32 lightMask) 3411{ 3412 return SL_RESULT_SUCCESS; 3413} 3414 3415static SLresult LEDArray_IsLEDArrayActivated(SLLEDArrayItf self, 3416 SLuint32 *lightMask) 3417{ 3418 return SL_RESULT_SUCCESS; 3419} 3420 3421static SLresult LEDArray_SetColor(SLLEDArrayItf self, SLuint8 index, 3422 const SLHSL *color) 3423{ 3424 return SL_RESULT_SUCCESS; 3425} 3426 3427static SLresult LEDArray_GetColor(SLLEDArrayItf self, SLuint8 index, 3428 SLHSL *color) 3429{ 3430 return SL_RESULT_SUCCESS; 3431} 3432 3433/*static*/ const struct SLLEDArrayItf_ LEDArray_LEDArrayItf = { 3434 LEDArray_ActivateLEDArray, 3435 LEDArray_IsLEDArrayActivated, 3436 LEDArray_SetColor, 3437 LEDArray_GetColor, 3438}; 3439 3440/* MetadataExtraction implementation */ 3441 3442static SLresult MetadataExtraction_GetItemCount(SLMetadataExtractionItf self, 3443 SLuint32 *pItemCount) 3444{ 3445 return SL_RESULT_SUCCESS; 3446} 3447 3448static SLresult MetadataExtraction_GetKeySize(SLMetadataExtractionItf self, 3449 SLuint32 index, SLuint32 *pKeySize) 3450{ 3451 return SL_RESULT_SUCCESS; 3452} 3453 3454static SLresult MetadataExtraction_GetKey(SLMetadataExtractionItf self, 3455 SLuint32 index, SLuint32 keySize, SLMetadataInfo *pKey) 3456{ 3457 return SL_RESULT_SUCCESS; 3458} 3459 3460static SLresult MetadataExtraction_GetValueSize(SLMetadataExtractionItf self, 3461 SLuint32 index, SLuint32 *pValueSize) 3462{ 3463 return SL_RESULT_SUCCESS; 3464} 3465 3466static SLresult MetadataExtraction_GetValue(SLMetadataExtractionItf self, 3467 SLuint32 index, SLuint32 valueSize, SLMetadataInfo *pValue) 3468{ 3469 return SL_RESULT_SUCCESS; 3470} 3471 3472static SLresult MetadataExtraction_AddKeyFilter(SLMetadataExtractionItf self, 3473 SLuint32 keySize, const void *pKey, SLuint32 keyEncoding, 3474 const SLchar *pValueLangCountry, SLuint32 valueEncoding, SLuint8 filterMask) 3475{ 3476 return SL_RESULT_SUCCESS; 3477} 3478 3479static SLresult MetadataExtraction_ClearKeyFilter(SLMetadataExtractionItf self) 3480{ 3481 return SL_RESULT_SUCCESS; 3482} 3483 3484/*static*/ const struct SLMetadataExtractionItf_ 3485 MetadataExtraction_MetadataExtractionItf = { 3486 MetadataExtraction_GetItemCount, 3487 MetadataExtraction_GetKeySize, 3488 MetadataExtraction_GetKey, 3489 MetadataExtraction_GetValueSize, 3490 MetadataExtraction_GetValue, 3491 MetadataExtraction_AddKeyFilter, 3492 MetadataExtraction_ClearKeyFilter 3493}; 3494 3495/* MetadataTraversal implementation */ 3496 3497static SLresult MetadataTraversal_SetMode(SLMetadataTraversalItf self, 3498 SLuint32 mode) 3499{ 3500 return SL_RESULT_SUCCESS; 3501} 3502 3503static SLresult MetadataTraversal_GetChildCount(SLMetadataTraversalItf self, 3504 SLuint32 *pCount) 3505{ 3506 return SL_RESULT_SUCCESS; 3507} 3508 3509static SLresult MetadataTraversal_GetChildMIMETypeSize( 3510 SLMetadataTraversalItf self, SLuint32 index, SLuint32 *pSize) 3511{ 3512 return SL_RESULT_SUCCESS; 3513} 3514 3515static SLresult MetadataTraversal_GetChildInfo(SLMetadataTraversalItf self, 3516 SLuint32 index, SLint32 *pNodeID, SLuint32 *pType, SLuint32 size, 3517 SLchar *pMimeType) 3518{ 3519 return SL_RESULT_SUCCESS; 3520} 3521 3522static SLresult MetadataTraversal_SetActiveNode(SLMetadataTraversalItf self, 3523 SLuint32 index) 3524{ 3525 return SL_RESULT_SUCCESS; 3526} 3527 3528/*static*/ const struct SLMetadataTraversalItf_ 3529 MetadataTraversal_MetadataTraversalItf = { 3530 MetadataTraversal_SetMode, 3531 MetadataTraversal_GetChildCount, 3532 MetadataTraversal_GetChildMIMETypeSize, 3533 MetadataTraversal_GetChildInfo, 3534 MetadataTraversal_SetActiveNode 3535}; 3536 3537/* MuteSolo implementation */ 3538 3539static SLresult MuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan, 3540 SLboolean mute) 3541{ 3542 return SL_RESULT_SUCCESS; 3543} 3544 3545static SLresult MuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan, 3546 SLboolean *pMute) 3547{ 3548 return SL_RESULT_SUCCESS; 3549} 3550 3551static SLresult MuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan, 3552 SLboolean solo) 3553{ 3554 return SL_RESULT_SUCCESS; 3555} 3556 3557static SLresult MuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan, 3558 SLboolean *pSolo) 3559{ 3560 return SL_RESULT_SUCCESS; 3561} 3562 3563static SLresult MuteSolo_GetNumChannels(SLMuteSoloItf self, 3564 SLuint8 *pNumChannels) 3565{ 3566 return SL_RESULT_SUCCESS; 3567} 3568 3569/*static*/ const struct SLMuteSoloItf_ MuteSolo_MuteSoloItf = { 3570 MuteSolo_SetChannelMute, 3571 MuteSolo_GetChannelMute, 3572 MuteSolo_SetChannelSolo, 3573 MuteSolo_GetChannelSolo, 3574 MuteSolo_GetNumChannels 3575}; 3576 3577/* Pitch implementation */ 3578 3579static SLresult Pitch_SetPitch(SLPitchItf self, SLpermille pitch) 3580{ 3581 return SL_RESULT_SUCCESS; 3582} 3583 3584static SLresult Pitch_GetPitch(SLPitchItf self, SLpermille *pPitch) 3585{ 3586 return SL_RESULT_SUCCESS; 3587} 3588 3589static SLresult Pitch_GetPitchCapabilities(SLPitchItf self, 3590 SLpermille *pMinPitch, SLpermille *pMaxPitch) 3591{ 3592 return SL_RESULT_SUCCESS; 3593} 3594 3595/*static*/ const struct SLPitchItf_ Pitch_PitchItf = { 3596 Pitch_SetPitch, 3597 Pitch_GetPitch, 3598 Pitch_GetPitchCapabilities 3599}; 3600 3601/* PlaybackRate implementation */ 3602 3603static SLresult PlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate) 3604{ 3605 return SL_RESULT_SUCCESS; 3606} 3607 3608static SLresult PlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate) 3609{ 3610 return SL_RESULT_SUCCESS; 3611} 3612 3613static SLresult PlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self, 3614 SLuint32 constraints) 3615{ 3616 return SL_RESULT_SUCCESS; 3617} 3618 3619static SLresult PlaybackRate_GetProperties(SLPlaybackRateItf self, 3620 SLuint32 *pProperties) 3621{ 3622 return SL_RESULT_SUCCESS; 3623} 3624 3625static SLresult PlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self, 3626 SLpermille rate, SLuint32 *pCapabilities) 3627{ 3628 return SL_RESULT_SUCCESS; 3629} 3630 3631static SLresult PlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index, 3632 SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize, 3633 SLuint32 *pCapabilities) 3634{ 3635 return SL_RESULT_SUCCESS; 3636} 3637 3638/*static*/ const struct SLPlaybackRateItf_ PlaybackRate_PlaybackRateItf = { 3639 PlaybackRate_SetRate, 3640 PlaybackRate_GetRate, 3641 PlaybackRate_SetPropertyConstraints, 3642 PlaybackRate_GetProperties, 3643 PlaybackRate_GetCapabilitiesOfRate, 3644 PlaybackRate_GetRateRange 3645}; 3646 3647/* PrefetchStatus implementation */ 3648 3649static SLresult PrefetchStatus_GetPrefetchStatus(SLPrefetchStatusItf self, 3650 SLuint32 *pStatus) 3651{ 3652 return SL_RESULT_SUCCESS; 3653} 3654 3655static SLresult PrefetchStatus_GetFillLevel(SLPrefetchStatusItf self, 3656 SLpermille *pLevel) 3657{ 3658 return SL_RESULT_SUCCESS; 3659} 3660 3661static SLresult PrefetchStatus_RegisterCallback(SLPrefetchStatusItf self, 3662 slPrefetchCallback callback, void *pContext) 3663{ 3664 return SL_RESULT_SUCCESS; 3665} 3666 3667static SLresult PrefetchStatus_SetCallbackEventsMask(SLPrefetchStatusItf self, 3668 SLuint32 eventFlags) 3669{ 3670 return SL_RESULT_SUCCESS; 3671} 3672 3673static SLresult PrefetchStatus_GetCallbackEventsMask(SLPrefetchStatusItf self, 3674 SLuint32 *pEventFlags) 3675{ 3676 return SL_RESULT_SUCCESS; 3677} 3678 3679static SLresult PrefetchStatus_SetFillUpdatePeriod(SLPrefetchStatusItf self, 3680 SLpermille period) 3681{ 3682 return SL_RESULT_SUCCESS; 3683} 3684 3685static SLresult PrefetchStatus_GetFillUpdatePeriod(SLPrefetchStatusItf self, 3686 SLpermille *pPeriod) 3687{ 3688 return SL_RESULT_SUCCESS; 3689} 3690 3691/*static*/ const struct SLPrefetchStatusItf_ 3692PrefetchStatus_PrefetchStatusItf = { 3693 PrefetchStatus_GetPrefetchStatus, 3694 PrefetchStatus_GetFillLevel, 3695 PrefetchStatus_RegisterCallback, 3696 PrefetchStatus_SetCallbackEventsMask, 3697 PrefetchStatus_GetCallbackEventsMask, 3698 PrefetchStatus_SetFillUpdatePeriod, 3699 PrefetchStatus_GetFillUpdatePeriod 3700}; 3701 3702/* RatePitch implementation */ 3703 3704static SLresult RatePitch_SetRate(SLRatePitchItf self, SLpermille rate) 3705{ 3706 return SL_RESULT_SUCCESS; 3707} 3708 3709static SLresult RatePitch_GetRate(SLRatePitchItf self, SLpermille *pRate) 3710{ 3711 return SL_RESULT_SUCCESS; 3712} 3713 3714static SLresult RatePitch_GetRatePitchCapabilities(SLRatePitchItf self, 3715 SLpermille *pMinRate, SLpermille *pMaxRate) 3716{ 3717 return SL_RESULT_SUCCESS; 3718} 3719 3720/*static*/ const struct SLRatePitchItf_ RatePitch_RatePitchItf = { 3721 RatePitch_SetRate, 3722 RatePitch_GetRate, 3723 RatePitch_GetRatePitchCapabilities 3724}; 3725 3726/* Record implementation */ 3727 3728static SLresult Record_SetRecordState(SLRecordItf self, SLuint32 state) 3729{ 3730 return SL_RESULT_SUCCESS; 3731} 3732 3733static SLresult Record_GetRecordState(SLRecordItf self, SLuint32 *pState) 3734{ 3735 return SL_RESULT_SUCCESS; 3736} 3737 3738static SLresult Record_SetDurationLimit(SLRecordItf self, SLmillisecond msec) 3739{ 3740 return SL_RESULT_SUCCESS; 3741} 3742 3743static SLresult Record_GetPosition(SLRecordItf self, SLmillisecond *pMsec) 3744{ 3745 return SL_RESULT_SUCCESS; 3746} 3747 3748static SLresult Record_RegisterCallback(SLRecordItf self, 3749 slRecordCallback callback, void *pContext) 3750{ 3751 return SL_RESULT_SUCCESS; 3752} 3753 3754static SLresult Record_SetCallbackEventsMask(SLRecordItf self, 3755 SLuint32 eventFlags) 3756{ 3757 return SL_RESULT_SUCCESS; 3758} 3759 3760static SLresult Record_GetCallbackEventsMask(SLRecordItf self, 3761 SLuint32 *pEventFlags) 3762{ 3763 return SL_RESULT_SUCCESS; 3764} 3765 3766static SLresult Record_SetMarkerPosition(SLRecordItf self, SLmillisecond mSec) 3767{ 3768 return SL_RESULT_SUCCESS; 3769} 3770 3771static SLresult Record_ClearMarkerPosition(SLRecordItf self) 3772{ 3773 return SL_RESULT_SUCCESS; 3774} 3775 3776static SLresult Record_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec) 3777{ 3778 return SL_RESULT_SUCCESS; 3779} 3780 3781static SLresult Record_SetPositionUpdatePeriod(SLRecordItf self, 3782 SLmillisecond mSec) 3783{ 3784 return SL_RESULT_SUCCESS; 3785} 3786 3787static SLresult Record_GetPositionUpdatePeriod(SLRecordItf self, 3788 SLmillisecond *pMsec) 3789{ 3790 return SL_RESULT_SUCCESS; 3791} 3792 3793/*static*/ const struct SLRecordItf_ Record_RecordItf = { 3794 Record_SetRecordState, 3795 Record_GetRecordState, 3796 Record_SetDurationLimit, 3797 Record_GetPosition, 3798 Record_RegisterCallback, 3799 Record_SetCallbackEventsMask, 3800 Record_GetCallbackEventsMask, 3801 Record_SetMarkerPosition, 3802 Record_ClearMarkerPosition, 3803 Record_GetMarkerPosition, 3804 Record_SetPositionUpdatePeriod, 3805 Record_GetPositionUpdatePeriod 3806}; 3807 3808/* ThreadSync implementation */ 3809 3810static SLresult ThreadSync_EnterCriticalSection(SLThreadSyncItf self) 3811{ 3812 return SL_RESULT_SUCCESS; 3813} 3814 3815static SLresult ThreadSync_ExitCriticalSection(SLThreadSyncItf self) 3816{ 3817 return SL_RESULT_SUCCESS; 3818} 3819 3820/*static*/ const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf = { 3821 ThreadSync_EnterCriticalSection, 3822 ThreadSync_ExitCriticalSection 3823}; 3824 3825/* Vibra implementation */ 3826 3827static SLresult Vibra_Vibrate(SLVibraItf self, SLboolean vibrate) 3828{ 3829 return SL_RESULT_SUCCESS; 3830} 3831 3832static SLresult Vibra_IsVibrating(SLVibraItf self, SLboolean *pVibrating) 3833{ 3834 return SL_RESULT_SUCCESS; 3835} 3836 3837static SLresult Vibra_SetFrequency(SLVibraItf self, SLmilliHertz frequency) 3838{ 3839 return SL_RESULT_SUCCESS; 3840} 3841 3842static SLresult Vibra_GetFrequency(SLVibraItf self, SLmilliHertz *pFrequency) 3843{ 3844 return SL_RESULT_SUCCESS; 3845} 3846 3847static SLresult Vibra_SetIntensity(SLVibraItf self, SLpermille intensity) 3848{ 3849 return SL_RESULT_SUCCESS; 3850} 3851 3852static SLresult Vibra_GetIntensity(SLVibraItf self, SLpermille *pIntensity) 3853{ 3854 return SL_RESULT_SUCCESS; 3855} 3856 3857/*static*/ const struct SLVibraItf_ Vibra_VibraItf = { 3858 Vibra_Vibrate, 3859 Vibra_IsVibrating, 3860 Vibra_SetFrequency, 3861 Vibra_GetFrequency, 3862 Vibra_SetIntensity, 3863 Vibra_GetIntensity 3864}; 3865 3866/* Visualization implementation */ 3867 3868static SLresult Visualization_RegisterVisualizationCallback( 3869 SLVisualizationItf self, slVisualizationCallback callback, void *pContext, 3870 SLmilliHertz rate) 3871{ 3872 struct Visualization_interface *this = 3873 (struct Visualization_interface *) self; 3874 this->mCallback = callback; 3875 this->mContext = pContext; 3876 this->mRate = rate; 3877 return SL_RESULT_SUCCESS; 3878} 3879 3880static SLresult Visualization_GetMaxRate(SLVisualizationItf self, 3881 SLmilliHertz *pRate) 3882{ 3883 if (NULL == pRate) 3884 return SL_RESULT_PARAMETER_INVALID; 3885 *pRate = 0; 3886 return SL_RESULT_SUCCESS; 3887} 3888 3889/*static*/ const struct SLVisualizationItf_ Visualization_VisualizationItf = { 3890 Visualization_RegisterVisualizationCallback, 3891 Visualization_GetMaxRate 3892}; 3893 3894/* BassBoost implementation */ 3895 3896static SLresult BassBoost_SetEnabled(SLBassBoostItf self, SLboolean enabled) 3897{ 3898 struct BassBoost_interface *this = (struct BassBoost_interface *) self; 3899 this->mEnabled = enabled; 3900 return SL_RESULT_SUCCESS; 3901} 3902 3903static SLresult BassBoost_IsEnabled(SLBassBoostItf self, SLboolean *pEnabled) 3904{ 3905 if (NULL == pEnabled) 3906 return SL_RESULT_PARAMETER_INVALID; 3907 struct BassBoost_interface *this = (struct BassBoost_interface *) self; 3908 *pEnabled = this->mEnabled; 3909 return SL_RESULT_SUCCESS; 3910} 3911 3912static SLresult BassBoost_SetStrength(SLBassBoostItf self, SLpermille strength) 3913{ 3914 struct BassBoost_interface *this = (struct BassBoost_interface *) self; 3915 this->mStrength = strength; 3916 return SL_RESULT_SUCCESS; 3917} 3918 3919static SLresult BassBoost_GetRoundedStrength(SLBassBoostItf self, 3920 SLpermille *pStrength) 3921{ 3922 if (NULL == pStrength) 3923 return SL_RESULT_PARAMETER_INVALID; 3924 struct BassBoost_interface *this = (struct BassBoost_interface *) self; 3925 *pStrength = this->mStrength; 3926 return SL_RESULT_SUCCESS; 3927} 3928 3929static SLresult BassBoost_IsStrengthSupported(SLBassBoostItf self, 3930 SLboolean *pSupported) 3931{ 3932 if (NULL == pSupported) 3933 return SL_RESULT_PARAMETER_INVALID; 3934 *pSupported = SL_BOOLEAN_TRUE; 3935 return SL_RESULT_SUCCESS; 3936} 3937 3938/*static*/ const struct SLBassBoostItf_ BassBoost_BassBoostItf = { 3939 BassBoost_SetEnabled, 3940 BassBoost_IsEnabled, 3941 BassBoost_SetStrength, 3942 BassBoost_GetRoundedStrength, 3943 BassBoost_IsStrengthSupported 3944}; 3945 3946/* 3DGrouping implementation */ 3947 3948static SLresult _3DGrouping_Set3DGroup(SL3DGroupingItf self, SLObjectItf group) 3949{ 3950 struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self; 3951 this->mGroup = group; 3952 return SL_RESULT_SUCCESS; 3953} 3954 3955static SLresult _3DGrouping_Get3DGroup(SL3DGroupingItf self, 3956 SLObjectItf *pGroup) 3957{ 3958 if (NULL == pGroup) 3959 return SL_RESULT_PARAMETER_INVALID; 3960 struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self; 3961 *pGroup = this->mGroup; 3962 return SL_RESULT_SUCCESS; 3963} 3964 3965/*static*/ const struct SL3DGroupingItf_ _3DGrouping_3DGroupingItf = { 3966 _3DGrouping_Set3DGroup, 3967 _3DGrouping_Get3DGroup 3968}; 3969 3970/* 3DMacroscopic implementation */ 3971 3972static SLresult _3DMacroscopic_SetSize(SL3DMacroscopicItf self, 3973 SLmillimeter width, SLmillimeter height, SLmillimeter depth) 3974{ 3975 return SL_RESULT_SUCCESS; 3976} 3977 3978static SLresult _3DMacroscopic_GetSize(SL3DMacroscopicItf self, 3979 SLmillimeter *pWidth, SLmillimeter *pHeight, SLmillimeter *pDepth) 3980{ 3981 return SL_RESULT_SUCCESS; 3982} 3983 3984static SLresult _3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self, 3985 SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll) 3986{ 3987 return SL_RESULT_SUCCESS; 3988} 3989 3990static SLresult _3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self, 3991 const SLVec3D *pFront, const SLVec3D *pAbove) 3992{ 3993 return SL_RESULT_SUCCESS; 3994} 3995 3996static SLresult _3DMacroscopic_Rotate(SL3DMacroscopicItf self, 3997 SLmillidegree theta, const SLVec3D *pAxis) 3998{ 3999 return SL_RESULT_SUCCESS; 4000} 4001 4002static SLresult _3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self, 4003 SLVec3D *pFront, SLVec3D *pUp) 4004{ 4005 return SL_RESULT_SUCCESS; 4006} 4007 4008/*static*/ const struct SL3DMacroscopicItf_ _3DMacroscopic_3DMacroscopicItf = { 4009 _3DMacroscopic_SetSize, 4010 _3DMacroscopic_GetSize, 4011 _3DMacroscopic_SetOrientationAngles, 4012 _3DMacroscopic_SetOrientationVectors, 4013 _3DMacroscopic_Rotate, 4014 _3DMacroscopic_GetOrientationVectors 4015}; 4016 4017/* 3DSource implementation */ 4018 4019static SLresult _3DSource_SetHeadRelative(SL3DSourceItf self, 4020 SLboolean headRelative) 4021{ 4022 return SL_RESULT_SUCCESS; 4023} 4024 4025static SLresult _3DSource_GetHeadRelative(SL3DSourceItf self, 4026 SLboolean *pHeadRelative) 4027{ 4028 return SL_RESULT_SUCCESS; 4029} 4030 4031static SLresult _3DSource_SetRolloffDistances(SL3DSourceItf self, 4032 SLmillimeter minDistance, SLmillimeter maxDistance) 4033{ 4034 return SL_RESULT_SUCCESS; 4035} 4036 4037static SLresult _3DSource_GetRolloffDistances(SL3DSourceItf self, 4038 SLmillimeter *pMinDistance, SLmillimeter *pMaxDistance) 4039{ 4040 return SL_RESULT_SUCCESS; 4041} 4042 4043static SLresult _3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self, 4044 SLboolean mute) 4045{ 4046 return SL_RESULT_SUCCESS; 4047} 4048 4049static SLresult _3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self, 4050 SLboolean *pMute) 4051{ 4052 return SL_RESULT_SUCCESS; 4053} 4054 4055static SLresult _3DSource_SetRolloffFactor(SL3DSourceItf self, 4056 SLpermille rolloffFactor) 4057{ 4058 return SL_RESULT_SUCCESS; 4059} 4060 4061static SLresult _3DSource_GetRolloffFactor(SL3DSourceItf self, 4062 SLpermille *pRolloffFactor) 4063{ 4064 return SL_RESULT_SUCCESS; 4065} 4066 4067static SLresult _3DSource_SetRoomRolloffFactor(SL3DSourceItf self, 4068 SLpermille roomRolloffFactor) 4069{ 4070 return SL_RESULT_SUCCESS; 4071} 4072 4073static SLresult _3DSource_GetRoomRolloffFactor(SL3DSourceItf self, 4074 SLpermille *pRoomRolloffFactor) 4075{ 4076 return SL_RESULT_SUCCESS; 4077} 4078 4079static SLresult _3DSource_SetRolloffModel(SL3DSourceItf self, SLuint8 model) 4080{ 4081 return SL_RESULT_SUCCESS; 4082} 4083 4084static SLresult _3DSource_GetRolloffModel(SL3DSourceItf self, SLuint8 *pModel) 4085{ 4086 return SL_RESULT_SUCCESS; 4087} 4088 4089static SLresult _3DSource_SetCone(SL3DSourceItf self, SLmillidegree innerAngle, 4090 SLmillidegree outerAngle, SLmillibel outerLevel) 4091{ 4092 return SL_RESULT_SUCCESS; 4093} 4094 4095static SLresult _3DSource_GetCone(SL3DSourceItf self, 4096 SLmillidegree *pInnerAngle, SLmillidegree *pOuterAngle, 4097 SLmillibel *pOuterLevel) 4098{ 4099 return SL_RESULT_SUCCESS; 4100} 4101 4102/*static*/ const struct SL3DSourceItf_ _3DSource_3DSourceItf = { 4103 _3DSource_SetHeadRelative, 4104 _3DSource_GetHeadRelative, 4105 _3DSource_SetRolloffDistances, 4106 _3DSource_GetRolloffDistances, 4107 _3DSource_SetRolloffMaxDistanceMute, 4108 _3DSource_GetRolloffMaxDistanceMute, 4109 _3DSource_SetRolloffFactor, 4110 _3DSource_GetRolloffFactor, 4111 _3DSource_SetRoomRolloffFactor, 4112 _3DSource_GetRoomRolloffFactor, 4113 _3DSource_SetRolloffModel, 4114 _3DSource_GetRolloffModel, 4115 _3DSource_SetCone, 4116 _3DSource_GetCone 4117}; 4118 4119/* Equalizer implementation */ 4120 4121static SLresult Equalizer_SetEnabled(SLEqualizerItf self, SLboolean enabled) 4122{ 4123 return SL_RESULT_SUCCESS; 4124} 4125 4126static SLresult Equalizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled) 4127{ 4128 return SL_RESULT_SUCCESS; 4129} 4130 4131static SLresult Equalizer_GetNumberOfBands(SLEqualizerItf self, 4132 SLuint16 *pNumBands) 4133{ 4134 return SL_RESULT_SUCCESS; 4135} 4136 4137static SLresult Equalizer_GetBandLevelRange(SLEqualizerItf self, 4138 SLmillibel *pMin, SLmillibel *pMax) 4139{ 4140 return SL_RESULT_SUCCESS; 4141} 4142 4143static SLresult Equalizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, 4144 SLmillibel level) 4145{ 4146 return SL_RESULT_SUCCESS; 4147} 4148 4149static SLresult Equalizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, 4150 SLmillibel *pLevel) 4151{ 4152 return SL_RESULT_SUCCESS; 4153} 4154 4155static SLresult Equalizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, 4156 SLmilliHertz *pCenter) 4157{ 4158 return SL_RESULT_SUCCESS; 4159} 4160 4161static SLresult Equalizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band, 4162 SLmilliHertz *pMin, SLmilliHertz *pMax) 4163{ 4164 return SL_RESULT_SUCCESS; 4165} 4166 4167static SLresult Equalizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, 4168 SLuint16 *pBand) 4169{ 4170 return SL_RESULT_SUCCESS; 4171} 4172 4173static SLresult Equalizer_GetCurrentPreset(SLEqualizerItf self, 4174 SLuint16 *pPreset) 4175{ 4176 return SL_RESULT_SUCCESS; 4177} 4178 4179static SLresult Equalizer_UsePreset(SLEqualizerItf self, SLuint16 index) 4180{ 4181 return SL_RESULT_SUCCESS; 4182} 4183 4184static SLresult Equalizer_GetNumberOfPresets(SLEqualizerItf self, 4185 SLuint16 *pNumPresets) 4186{ 4187 return SL_RESULT_SUCCESS; 4188} 4189 4190static SLresult Equalizer_GetPresetName(SLEqualizerItf self, SLuint16 index, 4191 const SLchar ** ppName) 4192{ 4193 return SL_RESULT_SUCCESS; 4194} 4195 4196/*static*/ const struct SLEqualizerItf_ Equalizer_EqualizerItf = { 4197 Equalizer_SetEnabled, 4198 Equalizer_IsEnabled, 4199 Equalizer_GetNumberOfBands, 4200 Equalizer_GetBandLevelRange, 4201 Equalizer_SetBandLevel, 4202 Equalizer_GetBandLevel, 4203 Equalizer_GetCenterFreq, 4204 Equalizer_GetBandFreqRange, 4205 Equalizer_GetBand, 4206 Equalizer_GetCurrentPreset, 4207 Equalizer_UsePreset, 4208 Equalizer_GetNumberOfPresets, 4209 Equalizer_GetPresetName 4210}; 4211 4212// PresetReverb implementation 4213 4214static SLresult PresetReverb_SetPreset(SLPresetReverbItf self, 4215 SLuint16 preset) 4216{ 4217 struct PresetReverb_interface *this = 4218 (struct PresetReverb_interface *) self; 4219 this->mPreset = preset; 4220 return SL_RESULT_SUCCESS; 4221} 4222 4223static SLresult PresetReverb_GetPreset(SLPresetReverbItf self, 4224 SLuint16 *pPreset) 4225{ 4226 if (NULL == pPreset) 4227 return SL_RESULT_PARAMETER_INVALID; 4228 struct PresetReverb_interface *this = 4229 (struct PresetReverb_interface *) self; 4230 *pPreset = this->mPreset; 4231 return SL_RESULT_SUCCESS; 4232} 4233 4234/*static*/ const struct SLPresetReverbItf_ PresetReverb_PresetReverbItf = { 4235 PresetReverb_SetPreset, 4236 PresetReverb_GetPreset 4237}; 4238 4239// EnvironmentalReverb implementation 4240 4241static SLresult EnvironmentalReverb_SetRoomLevel(SLEnvironmentalReverbItf self, 4242 SLmillibel room) 4243{ 4244 return SL_RESULT_SUCCESS; 4245} 4246 4247static SLresult EnvironmentalReverb_GetRoomLevel(SLEnvironmentalReverbItf self, 4248 SLmillibel *pRoom) 4249{ 4250 return SL_RESULT_SUCCESS; 4251} 4252 4253static SLresult EnvironmentalReverb_SetRoomHFLevel( 4254 SLEnvironmentalReverbItf self, SLmillibel roomHF) 4255{ 4256 return SL_RESULT_SUCCESS; 4257} 4258 4259static SLresult EnvironmentalReverb_GetRoomHFLevel( 4260 SLEnvironmentalReverbItf self, SLmillibel *pRoomHF) 4261{ 4262 return SL_RESULT_SUCCESS; 4263} 4264 4265static SLresult EnvironmentalReverb_SetDecayTime( 4266 SLEnvironmentalReverbItf self, SLmillisecond decayTime) 4267{ 4268 return SL_RESULT_SUCCESS; 4269} 4270 4271static SLresult EnvironmentalReverb_GetDecayTime( 4272 SLEnvironmentalReverbItf self, SLmillisecond *pDecayTime) 4273{ 4274 return SL_RESULT_SUCCESS; 4275} 4276 4277static SLresult EnvironmentalReverb_SetDecayHFRatio( 4278 SLEnvironmentalReverbItf self, SLpermille decayHFRatio) 4279{ 4280 return SL_RESULT_SUCCESS; 4281} 4282 4283static SLresult EnvironmentalReverb_GetDecayHFRatio( 4284 SLEnvironmentalReverbItf self, SLpermille *pDecayHFRatio) 4285{ 4286 return SL_RESULT_SUCCESS; 4287} 4288 4289static SLresult EnvironmentalReverb_SetReflectionsLevel( 4290 SLEnvironmentalReverbItf self, SLmillibel reflectionsLevel) 4291{ 4292 return SL_RESULT_SUCCESS; 4293} 4294 4295static SLresult EnvironmentalReverb_GetReflectionsLevel( 4296 SLEnvironmentalReverbItf self, SLmillibel *pReflectionsLevel) 4297{ 4298 return SL_RESULT_SUCCESS; 4299} 4300 4301static SLresult EnvironmentalReverb_SetReflectionsDelay( 4302 SLEnvironmentalReverbItf self, SLmillisecond reflectionsDelay) 4303{ 4304 return SL_RESULT_SUCCESS; 4305} 4306 4307static SLresult EnvironmentalReverb_GetReflectionsDelay( 4308 SLEnvironmentalReverbItf self, SLmillisecond *pReflectionsDelay) 4309{ 4310 return SL_RESULT_SUCCESS; 4311} 4312 4313static SLresult EnvironmentalReverb_SetReverbLevel( 4314 SLEnvironmentalReverbItf self, SLmillibel reverbLevel) 4315{ 4316 return SL_RESULT_SUCCESS; 4317} 4318 4319static SLresult EnvironmentalReverb_GetReverbLevel( 4320 SLEnvironmentalReverbItf self, SLmillibel *pReverbLevel) 4321{ 4322 return SL_RESULT_SUCCESS; 4323} 4324 4325static SLresult EnvironmentalReverb_SetReverbDelay( 4326 SLEnvironmentalReverbItf self, SLmillisecond reverbDelay) 4327{ 4328 return SL_RESULT_SUCCESS; 4329} 4330 4331static SLresult EnvironmentalReverb_GetReverbDelay( 4332 SLEnvironmentalReverbItf self, SLmillisecond *pReverbDelay) 4333{ 4334 return SL_RESULT_SUCCESS; 4335} 4336 4337static SLresult EnvironmentalReverb_SetDiffusion( 4338 SLEnvironmentalReverbItf self, SLpermille diffusion) 4339{ 4340 return SL_RESULT_SUCCESS; 4341} 4342 4343static SLresult EnvironmentalReverb_GetDiffusion(SLEnvironmentalReverbItf self, 4344 SLpermille *pDiffusion) 4345{ 4346 return SL_RESULT_SUCCESS; 4347} 4348 4349static SLresult EnvironmentalReverb_SetDensity(SLEnvironmentalReverbItf self, 4350 SLpermille density) 4351{ 4352 return SL_RESULT_SUCCESS; 4353} 4354 4355static SLresult EnvironmentalReverb_GetDensity(SLEnvironmentalReverbItf self, 4356 SLpermille *pDensity) 4357{ 4358 return SL_RESULT_SUCCESS; 4359} 4360 4361static SLresult EnvironmentalReverb_SetEnvironmentalReverbProperties( 4362 SLEnvironmentalReverbItf self, 4363 const SLEnvironmentalReverbSettings *pProperties) 4364{ 4365 return SL_RESULT_SUCCESS; 4366} 4367 4368static SLresult EnvironmentalReverb_GetEnvironmentalReverbProperties( 4369 SLEnvironmentalReverbItf self, SLEnvironmentalReverbSettings *pProperties) 4370{ 4371 return SL_RESULT_SUCCESS; 4372} 4373 4374/*static*/ const struct SLEnvironmentalReverbItf_ 4375 EnvironmentalReverb_EnvironmentalReverbItf = { 4376 EnvironmentalReverb_SetRoomLevel, 4377 EnvironmentalReverb_GetRoomLevel, 4378 EnvironmentalReverb_SetRoomHFLevel, 4379 EnvironmentalReverb_GetRoomHFLevel, 4380 EnvironmentalReverb_SetDecayTime, 4381 EnvironmentalReverb_GetDecayTime, 4382 EnvironmentalReverb_SetDecayHFRatio, 4383 EnvironmentalReverb_GetDecayHFRatio, 4384 EnvironmentalReverb_SetReflectionsLevel, 4385 EnvironmentalReverb_GetReflectionsLevel, 4386 EnvironmentalReverb_SetReflectionsDelay, 4387 EnvironmentalReverb_GetReflectionsDelay, 4388 EnvironmentalReverb_SetReverbLevel, 4389 EnvironmentalReverb_GetReverbLevel, 4390 EnvironmentalReverb_SetReverbDelay, 4391 EnvironmentalReverb_GetReverbDelay, 4392 EnvironmentalReverb_SetDiffusion, 4393 EnvironmentalReverb_GetDiffusion, 4394 EnvironmentalReverb_SetDensity, 4395 EnvironmentalReverb_GetDensity, 4396 EnvironmentalReverb_SetEnvironmentalReverbProperties, 4397 EnvironmentalReverb_GetEnvironmentalReverbProperties 4398}; 4399 4400// Virtualizer implementation 4401 4402static SLresult Virtualizer_SetEnabled(SLVirtualizerItf self, SLboolean enabled) 4403{ 4404 struct Virtualizer_interface *this = (struct Virtualizer_interface *) self; 4405 this->mEnabled = enabled; 4406 return SL_RESULT_SUCCESS; 4407} 4408 4409static SLresult Virtualizer_IsEnabled(SLVirtualizerItf self, 4410 SLboolean *pEnabled) 4411{ 4412 if (NULL == pEnabled) 4413 return SL_RESULT_PARAMETER_INVALID; 4414 struct Virtualizer_interface *this = (struct Virtualizer_interface *) self; 4415 *pEnabled = this->mEnabled; 4416 return SL_RESULT_SUCCESS; 4417} 4418 4419static SLresult Virtualizer_SetStrength(SLVirtualizerItf self, 4420 SLpermille strength) 4421{ 4422 struct Virtualizer_interface *this = (struct Virtualizer_interface *) self; 4423 this->mStrength = strength; 4424 return SL_RESULT_SUCCESS; 4425} 4426 4427static SLresult Virtualizer_GetRoundedStrength(SLVirtualizerItf self, 4428 SLpermille *pStrength) 4429{ 4430 if (NULL == pStrength) 4431 return SL_RESULT_PARAMETER_INVALID; 4432 struct Virtualizer_interface *this = (struct Virtualizer_interface *) self; 4433 *pStrength = this->mStrength; 4434 return SL_RESULT_SUCCESS; 4435} 4436 4437static SLresult Virtualizer_IsStrengthSupported(SLVirtualizerItf self, 4438 SLboolean *pSupported) 4439{ 4440 if (NULL == pSupported) 4441 return SL_RESULT_PARAMETER_INVALID; 4442 *pSupported = SL_BOOLEAN_TRUE; 4443 return SL_RESULT_SUCCESS; 4444} 4445 4446/*static*/ const struct SLVirtualizerItf_ Virtualizer_VirtualizerItf = { 4447 Virtualizer_SetEnabled, 4448 Virtualizer_IsEnabled, 4449 Virtualizer_SetStrength, 4450 Virtualizer_GetRoundedStrength, 4451 Virtualizer_IsStrengthSupported 4452}; 4453 4454/* Initial entry points */ 4455 4456#ifndef __cplusplus 4457 4458SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 4459 const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 4460 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 4461{ 4462 if (NULL == pEngine) 4463 return SL_RESULT_PARAMETER_INVALID; 4464 *pEngine = NULL; 4465 // default values 4466 SLboolean threadSafe = SL_BOOLEAN_TRUE; 4467 SLboolean lossOfControl = SL_BOOLEAN_FALSE; 4468 if (NULL != pEngineOptions) { 4469 SLuint32 i; 4470 const SLEngineOption *option = pEngineOptions; 4471 for (i = 0; i < numOptions; ++i, ++option) { 4472 switch (option->feature) { 4473 case SL_ENGINEOPTION_THREADSAFE: 4474 threadSafe = (SLboolean) option->data; 4475 break; 4476 case SL_ENGINEOPTION_LOSSOFCONTROL: 4477 lossOfControl = (SLboolean) option->data; 4478 break; 4479 default: 4480 return SL_RESULT_PARAMETER_INVALID; 4481 } 4482 } 4483 } 4484 unsigned exposedMask; 4485 SLresult result = checkInterfaces(&Engine_class, numInterfaces, 4486 pInterfaceIds, pInterfaceRequired, &exposedMask); 4487 if (SL_RESULT_SUCCESS != result) 4488 return result; 4489 struct Engine_class *this = 4490 (struct Engine_class *) construct(&Engine_class, exposedMask); 4491 if (NULL == this) 4492 return SL_RESULT_MEMORY_FAILURE; 4493 this->mThreadSafe = threadSafe; 4494 this->mLossOfControl = lossOfControl; 4495 *pEngine = &this->mObject.mItf; 4496 return SL_RESULT_SUCCESS; 4497} 4498 4499SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces( 4500 SLuint32 *pNumSupportedInterfaces) 4501{ 4502 if (NULL == pNumSupportedInterfaces) 4503 return SL_RESULT_PARAMETER_INVALID; 4504 *pNumSupportedInterfaces = Engine_class.mInterfaceCount; 4505 return SL_RESULT_SUCCESS; 4506} 4507 4508SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, 4509 SLInterfaceID *pInterfaceId) 4510{ 4511 if (sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]) < index) 4512 return SL_RESULT_PARAMETER_INVALID; 4513 if (NULL == pInterfaceId) 4514 return SL_RESULT_PARAMETER_INVALID; 4515 *pInterfaceId = &SL_IID_array[Engine_interfaces[index].mMPH]; 4516 return SL_RESULT_SUCCESS; 4517} 4518 4519#endif // !__cplusplus 4520 4521#ifdef USE_OUTPUTMIXEXT 4522 4523/* OutputMixExt implementation */ 4524 4525// Used by SDL and Android but not specific to or dependent on either platform 4526 4527static void OutputMixExt_FillBuffer(SLOutputMixExtItf self, void *pBuffer, 4528 SLuint32 size) 4529{ 4530 // Force to be a multiple of a frame, assumes stereo 16-bit PCM 4531 size &= ~3; 4532 struct OutputMixExt_interface *thisExt = 4533 (struct OutputMixExt_interface *) self; 4534 struct OutputMix_interface *this = 4535 &((struct OutputMix_class *) thisExt->this)->mOutputMix; 4536 unsigned activeMask = this->mActiveMask; 4537 struct Track *track = &this->mTracks[0]; 4538 unsigned i; 4539 SLboolean mixBufferHasData = SL_BOOLEAN_FALSE; 4540 // FIXME O(32) loop even when few tracks are active. 4541 // To avoid loop, use activeMask to check for active track(s) 4542 // and decide whether we actually need to copy or mix. 4543 for (i = 0; 0 != activeMask; ++i, ++track, activeMask >>= 1) { 4544 assert(i < 32); 4545 if (!(activeMask & 1)) 4546 continue; 4547 // track is allocated 4548 struct Play_interface *play = track->mPlay; 4549 if (NULL == play) 4550 continue; 4551 // track is initialized 4552 if (SL_PLAYSTATE_PLAYING != play->mState) 4553 continue; 4554 // track is playing 4555 void *dstWriter = pBuffer; 4556 unsigned desired = size; 4557 SLboolean trackContributedToMix = SL_BOOLEAN_FALSE; 4558 while (desired > 0) { 4559 struct BufferQueue_interface *bufferQueue; 4560 const struct BufferHeader *oldFront, *newFront, *rear; 4561 unsigned actual = desired; 4562 if (track->mAvail < actual) 4563 actual = track->mAvail; 4564 // force actual to be a frame multiple 4565 if (actual > 0) { 4566 // FIXME check for either mute or volume 0 4567 // in which case skip the input buffer processing 4568 assert(NULL != track->mReader); 4569 // FIXME && gain == 1.0 4570 if (mixBufferHasData) { 4571 stereo *mixBuffer = (stereo *) dstWriter; 4572 const stereo *source = (const stereo *) track->mReader; 4573 unsigned j; 4574 for (j = 0; j < actual; j += sizeof(stereo), ++mixBuffer, 4575 ++source) { 4576 // apply gain here 4577 mixBuffer->left += source->left; 4578 mixBuffer->right += source->right; 4579 } 4580 } else { 4581 memcpy(dstWriter, track->mReader, actual); 4582 trackContributedToMix = SL_BOOLEAN_TRUE; 4583 } 4584 dstWriter = (char *) dstWriter + actual; 4585 desired -= actual; 4586 track->mReader = (char *) track->mReader + actual; 4587 track->mAvail -= actual; 4588 if (track->mAvail == 0) { 4589 bufferQueue = track->mBufferQueue; 4590 if (NULL != bufferQueue) { 4591 oldFront = bufferQueue->mFront; 4592 rear = bufferQueue->mRear; 4593 assert(oldFront != rear); 4594 newFront = oldFront; 4595 if (++newFront == 4596 &bufferQueue->mArray[bufferQueue->mNumBuffers]) 4597 newFront = bufferQueue->mArray; 4598 bufferQueue->mFront = (struct BufferHeader *) newFront; 4599 assert(0 < bufferQueue->mState.count); 4600 --bufferQueue->mState.count; 4601 // FIXME here or in Enqueue? 4602 ++bufferQueue->mState.playIndex; 4603 // FIXME a good time to do an early warning 4604 // callback depending on buffer count 4605 } 4606 } 4607 continue; 4608 } 4609 // actual == 0 4610 bufferQueue = track->mBufferQueue; 4611 if (NULL != bufferQueue) { 4612 oldFront = bufferQueue->mFront; 4613 rear = bufferQueue->mRear; 4614 if (oldFront != rear) { 4615got_one: 4616 assert(0 < bufferQueue->mState.count); 4617 track->mReader = oldFront->mBuffer; 4618 track->mAvail = oldFront->mSize; 4619 continue; 4620 } 4621 // FIXME should be able to configure when to 4622 // kick off the callback e.g. high/low water-marks etc. 4623 // need data but none available, attempt a desperate callback 4624 slBufferQueueCallback callback = bufferQueue->mCallback; 4625 if (NULL != callback) { 4626 (*callback)((SLBufferQueueItf) bufferQueue, 4627 bufferQueue->mContext); 4628 // if lucky, the callback enqueued a buffer 4629 if (rear != bufferQueue->mRear) 4630 goto got_one; 4631 // unlucky, queue still empty, the callback failed 4632 } 4633 // here on underflow due to no callback, or failed callback 4634 // FIXME underflow, send silence (or previous buffer?) 4635 // we did a callback to try to kick start again but failed 4636 // should log this 4637 } 4638 // no buffer queue or underflow, clear out rest of partial buffer 4639 if (!mixBufferHasData && trackContributedToMix) 4640 memset(dstWriter, 0, actual); 4641 break; 4642 } 4643 if (trackContributedToMix) 4644 mixBufferHasData = SL_BOOLEAN_TRUE; 4645 } 4646 // No active tracks, so output silence 4647 if (!mixBufferHasData) 4648 memset(pBuffer, 0, size); 4649} 4650 4651/*static*/ const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf = { 4652 OutputMixExt_FillBuffer 4653}; 4654 4655#endif // USE_OUTPUTMIXEXT 4656 4657#ifdef USE_SDL 4658 4659// FIXME move to separate source file 4660 4661/* SDL platform implementation */ 4662 4663static void SDLCALL SDL_callback(void *context, Uint8 *stream, int len) 4664{ 4665 assert(len > 0); 4666 OutputMixExt_FillBuffer((SLOutputMixExtItf) context, stream, 4667 (SLuint32) len); 4668} 4669 4670void SDL_start(SLObjectItf self) 4671{ 4672 //assert(self != NULL); 4673 // FIXME make this an operation on Object: GetClass 4674 //struct Object_interface *this = (struct Object_interface *) self; 4675 //assert(&OutputMix_class == this->mClass); 4676 SLresult result; 4677 SLOutputMixExtItf OutputMixExt; 4678 result = (*self)->GetInterface(self, SL_IID_OUTPUTMIXEXT, &OutputMixExt); 4679 assert(SL_RESULT_SUCCESS == result); 4680 4681 SDL_AudioSpec fmt; 4682 fmt.freq = 44100; 4683 fmt.format = AUDIO_S16; 4684 fmt.channels = 2; 4685 fmt.samples = 256; 4686 fmt.callback = SDL_callback; 4687 // FIXME should be a GetInterface 4688 // fmt.userdata = &((struct OutputMix_class *) this)->mOutputMixExt; 4689 fmt.userdata = (void *) OutputMixExt; 4690 4691 if (SDL_OpenAudio(&fmt, NULL) < 0) { 4692 fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); 4693 exit(1); 4694 } 4695 SDL_PauseAudio(0); 4696} 4697 4698#endif // USE_SDL 4699 4700/* End */ 4701