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