sles.cpp revision 29b9008a17cae003590a5ff361e98809f02e3025
1d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Copyright 2010 The Android Open Source Project */
2d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* OpenSL ES prototype */
4d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
5d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include "OpenSLES.h"
6d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include <stddef.h> // offsetof
7d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include <stdlib.h> // malloc
8d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include <string.h> // memcmp
9bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include <stdio.h>  // debugging
10bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include <assert.h> // debugging
1129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#include <pthread.h>
12bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
13bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "MPH.h"
14bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "MPH_to.h"
152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <sndfile.h>
18bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
19bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <SDL/SDL_audio.h>
22bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SDL
23bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
24d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_ANDROID
25d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#include <unistd.h>
26d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#include "media/AudioSystem.h"
27d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#include "media/AudioTrack.h"
28d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
29d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
30bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
31bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "OutputMixExt.h"
322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
33d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
34d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Forward declarations */
35d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
36bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenextern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
37bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
38bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef __cplusplus
39bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define this this_
40bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
41d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
42d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private types */
43d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
44bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Hook functions
45bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
46bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef void (*VoidHook)(void *self);
47bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef SLresult (*StatusHook)(void *self);
48bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
49bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Describes how an interface is related to a given class
50bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
51bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_IMPLICIT           0
52bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_EXPLICIT           1
53bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_OPTIONAL           2
54bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC            3
55bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_GAME       INTERFACE_DYNAMIC
56bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_MUSIC      INTERFACE_DYNAMIC
57bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_MUSIC_GAME INTERFACE_DYNAMIC
58bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_EXPLICIT_GAME      INTERFACE_EXPLICIT
59bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_GAME               INTERFACE_OPTIONAL
60bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_GAME_MUSIC         INTERFACE_OPTIONAL
61bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_MUSIC_GAME         INTERFACE_OPTIONAL
62bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_OPTIONAL_DYNAMIC   INTERFACE_DYNAMIC
63bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_PHONE_GAME         INTERFACE_OPTIONAL
64bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_TBD                INTERFACE_IMPLICIT
65bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
66bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Maps an interface ID to its offset within the class that exposes it
67bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
68d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct iid_vtable {
69bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned char mMPH;
7029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned char mInterface;   // relationship
71bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    /*size_t*/ unsigned short mOffset;
72bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
73bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
74bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Per-class const data shared by all instances of the same class
75bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
76bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct class_ {
77bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // needed by all classes (class class, the superclass of all classes)
78bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *mInterfaces;
79bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mInterfaceCount;
80bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const signed char *mMPH_to_index;
81bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME not yet used
82bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //const char * const mName;
83bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t mSize;
84bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mObjectID;
85bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    StatusHook mRealize;
8629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    StatusHook mResume;
87bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mDestroy;
8829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // append per-class data here
89d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
90d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
91d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_OUTPUTMIXEXT
92d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
93bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Track describes each input to OutputMixer
94bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME not for Android
95bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
96bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Track {
97bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLDataFormat_PCM *mDfPcm;
98bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *mBufferQueue;
99bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *mPlay; // mixer examines this track if non-NULL
100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mReader;    // pointer to next frame in BufferHeader.mBuffer
101bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mAvail;        // number of available bytes
102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
104d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
105d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// BufferHeader describes each element of a BufferQueue, other than the data
107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct BufferHeader {
109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mBuffer;
110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mSize;
111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// stereo is a frame consisting of a pair of 16-bit PCM samples
116bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
117bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef struct {
118bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short left;
119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short right;
120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} stereo;
121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
124bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_SNDFILE
125bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct SndFile {
127bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // save URI also?
128bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLchar *mPathname;
129bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SNDFILE *mSNDFILE;
130bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // These are used when Enqueue returns SL_RESULT_BUFFER_INSUFFICIENT
131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mRetryBuffer;
132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mRetrySize;
133bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mIs0; // which buffer to use next
134bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME magic numbers
135bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short mBuffer0[512];
136bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short mBuffer1[512];
137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
139bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
140bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Device table (change this when you port!) */
1422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HEADSET 1
1442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_headset = {
1462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "headset",
1472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_ATTACHED_WIRED,
1482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_USER,
1492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HEADSET,
1502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
1512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
1542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
1552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
1562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
1572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
1582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HANDSFREE 2
1602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_handsfree = {
1622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "handsfree",
1632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_INTEGRATED,
1642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_ENVIRONMENT,
1652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HANDSET,
1662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
1672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
1702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
1712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
1722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
1732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
1742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
17629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#if 0
17729b9008a17cae003590a5ff361e98809f02e3025Glenn Kastenstatic const SLLEDDescriptor SLLEDDescriptor_default = {
17829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    8,  // ledCount
17929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    2,  // primaryLED
18029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    12  // colorMask
18129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten};
18229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
18329b9008a17cae003590a5ff361e98809f02e3025Glenn Kastenstatic const SLuint32 LED_ids[] = {SL_DEFAULTDEVICEID_LED};
18429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#endif
18529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
186bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface structures */
1872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
188bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DCommit_interface {
189bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DCommitItf_ *mItf;
19029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mDeferred;
192bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
193d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
194bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DDoppler_interface {
195bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DDopplerItf_ *mItf;
19629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
197bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    union Cartesian_Spherical1 {
198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLVec3D mCartesian;
199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        struct {
200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mAzimuth;
201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mElevation;
202bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mSpeed;
203bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        } mSpherical;
204bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } mVelocity;
205bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mDopplerFactor;
206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
207d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
208bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DGrouping_interface {
209bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DGroupingItf_ *mItf;
21029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLObjectItf mGroup;
212bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
213d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
214bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DLocation_interface {
215bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DLocationItf_ *mItf;
21629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
217bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    union Cartesian_Spherical2 {
218bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLVec3D mCartesian;
219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        struct {
220bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mAzimuth;
221bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mElevation;
222bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mDistance;
223bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        } mSpherical;
224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } mLocation;
225bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mHeading;
226bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mPitch;
227bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mRoll;
228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mFront;
229bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mAbove;
230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mUp;
231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
232d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
233bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DMacroscopic_interface {
234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DMacroscopicItf_ *mItf;
23529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
236d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
237d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
238bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DSource_interface {
239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DSourceItf_ *mItf;
24029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
242d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
243bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioDecoderCapabilities_interface {
244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioDecoderCapabilitiesItf_ *mItf;
24529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
246d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
247d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioEncoder_interface {
249bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioEncoderItf_ *mItf;
25029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
251bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLAudioEncoderSettings mSettings;
252bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
253bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
254bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioEncoderCapabilities_interface {
255bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioEncoderCapabilitiesItf_ *mItf;
25629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
257bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
258bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioIODeviceCapabilities_interface {
260bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioIODeviceCapabilitiesItf_ *mItf;
26129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
262bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
263bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
264bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct BassBoost_interface {
265bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLBassBoostItf_ *mItf;
26629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
267bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnabled;
268bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStrength;
269d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
270d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
271d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct BufferQueue_interface {
272bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLBufferQueueItf_ *mItf;
27329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
274d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLBufferQueueState mState;
275d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback mCallback;
276d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
277d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 mNumBuffers;
278bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader *mArray;
279bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader *mFront, *mRear;
280bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // saves a malloc in the typical case
281bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define BUFFER_HEADER_TYPICAL 4
282bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader mTypical[BUFFER_HEADER_TYPICAL+1];
283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
285bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DeviceVolume_interface {
286bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDeviceVolumeItf_ *mItf;
28729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
288bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint32 mVolume;     // FIXME should be per-device
289d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
290d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DynamicInterfaceManagement_interface {
292bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDynamicInterfaceManagementItf_ *mItf;
29329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
294bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mAddedMask;    // added interfaces, a subset of exposed interfaces
295bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slDynamicInterfaceManagementCallback mCallback;
296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
297d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
298d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
299bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DynamicSource_interface {
300bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDynamicSourceItf_ *mItf;
30129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
302d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
303d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
304bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EffectSend_interface {
305bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEffectSendItf_ *mItf;
30629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
307d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
308d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
309bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Engine_interface {
310bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEngineItf_ *mItf;
31129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
31229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLboolean mLossOfControlGlobal;
31329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Per-class non-const data such as vector of created objects.
31429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // Each engine is its own universe.
31529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // SLuint32 mInstanceCount;
31629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // Vector<Type> instances;
3172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
318d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
319bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EngineCapabilities_interface {
320bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEngineCapabilitiesItf_ *mItf;
32129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
324bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EnvironmentalReverb_interface {
325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEnvironmentalReverbItf_ *mItf;
32629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
329bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Equalizer_interface {
330bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEqualizerItf_ *mItf;
33129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
334bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct LEDArray_interface {
335bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLLEDArrayItf_ *mItf;
33629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
33729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // SLHSL *mHSL;
3382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
340bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MetaDataExtraction_interface {
341bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMetaDataExractionItf_ *mItf;
34229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
345bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MetaDataTraversal_interface {
346bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMetaDataTraversalItf_ *mItf;
34729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
350bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDIMessage_interface {
351bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDIMessageItf_ *mItf;
35229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDIMuteSolo_interface {
356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDIMuteSoloItf_ *mItf;
35729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
360bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDITempo_interface {
361bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDITempoItf_ *mItf;
36229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
365bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDITime_interface {
366bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDITimeItf_ *mItf;
36729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
370bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MuteSolo_interface {
371bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMuteSoloItf_ *mItf;
37229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
3732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
375bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Object_interface {
376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLObjectItf_ *mItf;
37729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME probably not needed for an Object, as it is always first,
37829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // but look for lingering code that assumes it is here before deleting
37929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
380bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *mClass;
381bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    volatile SLuint32 mState;
382bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slObjectCallback mCallback;
383bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mExposedMask;  // exposed interfaces
38529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned mLossOfControlMask;    // interfaces with loss of control enabled
386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint32 mPriority;
387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mPreemptable;
38829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    pthread_mutex_t mMutex;
389bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME also an object ID for RPC
390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME and a human-readable name for debugging
3912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
393bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMix_interface {
394bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLOutputMixItf_ *mItf;
39529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
396d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_OUTPUTMIXEXT
397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mActiveMask;   // 1 bit per active track
398bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Track mTracks[32];
399d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
4002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
402bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
403bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMixExt_interface {
404bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLOutputMixExtItf_ *mItf;
40529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
4062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
407bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
4082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Pitch_interface {
410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPitchItf_ *mItf;
41129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
4122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Play_interface {
415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPlayItf_ *mItf;
41629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
417bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    volatile SLuint32 mState;
418bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mDuration;
419bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPosition;
420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // unsigned mPositionSamples;  // position in sample units
421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slPlayCallback mCallback;
422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mEventFlags;
424bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mMarkerPosition;
425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPositionUpdatePeriod;
4262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PlaybackRate_interface {
429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPlaybackRateItf_ *mItf;
43029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
4312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
433bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PrefetchStatus_interface {
434bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPrefetchStatusItf_ *mItf;
43529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
4362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PresetReverb_interface {
439bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPresetReverbItf_ *mItf;
44029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 mPreset;
4422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct RatePitch_interface {
445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLRatePitchItf_ *mItf;
44629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
4472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Record_interface {
450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLRecordItf_ *mItf;
45129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
452d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
453d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Seek_interface {
455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLSeekItf_ *mItf;
45629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPos;
458bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mLoopEnabled;
459bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mStartPos;
460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mEndPos;
461bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
462d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
463bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct ThreadSync_interface {
464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLThreadSyncItf_ *mItf;
46529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
466d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
467d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
468bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Vibra_interface {
469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVibraItf_ *mItf;
47029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
471d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
472d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Virtualizer_interface {
474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVirtualizerItf_ *mItf;
47529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnabled;
477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStrength;
4782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Visualization_interface {
481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVisualizationItf_ *mItf;
48229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slVisualizationCallback mCallback;
484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz mRate;
486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Volume_interface {
489bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVolumeItf_ *mItf;
49029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *mThis;
491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel mLevel;
492bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mMute;
493bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnableStereoPosition;
494bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStereoPosition;
495bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
496bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
497bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Class structures */
498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DGroup_class {
5002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
5062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
508d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct AudioPlayer_class {
509d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
510d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
511d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface mPlay;
512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface m3DGrouping;
514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface mBufferQueue;
5172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct EffectSend_interface mEffectSend;
5182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MuteSolo_interface mMuteSolo;
5192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
5202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
5212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct PrefetchStatus_interface mPrefetchStatus;
5222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct RatePitch_interface mRatePitch;
5232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
5242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface mVolume;
5252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // optional interfaces
526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
530bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Pitch_interface mPitch;
532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PlaybackRate_interface mPlaybackRate;
534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
5362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // rest of fields are not related to the interfaces
5372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct SndFile mSndFile;
539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
540d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_ANDROID
541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME union per kind of AudioPlayer: MediaPlayer, AudioTrack, etc.
542d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    android::AudioTrack *mAudioTrack;
543d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    pthread_t mThread;
544d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
5452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioRecorder_class {
548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Record_interface mRecord;
5522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioEncoder_interface mAudioEncoder;
553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
554bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
557bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
558d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
559d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
560d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
561bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Engine_class {
562bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated implicit interfaces
563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Engine_interface mEngine;
566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EngineCapabilities_interface mEngineCapabilities;
567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct ThreadSync_interface mThreadSync;
568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated explicit interfaces
569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioIODeviceCapabilities_interface mAudioIODeviceCapabilities;
570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioDecoderCapabilities_interface mAudioDecoderCapabilities;
571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoderCapabilities_interface mAudioEncoderCapabilities;
572bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface m3DCommit;
573bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
574bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface mDeviceVolume;
575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // additional fields not associated with interfaces
576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mThreadSafe;
577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct LEDDevice_class {
580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
581bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct LEDArray_interface mLED;
584bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //
585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mDeviceID;
586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
5882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Listener_class {
589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
5932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DLocation_interface m3DLocation;
5942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MetadataExtractor_class {
597bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
6002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicSource_interface mDynamicSource;
6012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
6022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
6032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
6042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
6052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MidiPlayer_class {
606bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
6072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
6082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
6092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface mPlay;
610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface m3DGrouping;
612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface mBufferQueue;
615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EffectSend_interface mEffectSend;
616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MuteSolo_interface mMuteSolo;
617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDIMessage_interface mMIDIMessage;
620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDITime_interface mMIDITime;
621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDITempo_interface mMIDITempo;
622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDIMuteSolo_interface mMIDIMuteSolo;
623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PrefetchStatus_interface mPrefetchStatus;
6242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
625bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface mVolume;
626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
629bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Pitch_interface mPitch;
633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PlaybackRate_interface mPlaybackRate;
635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
6372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
6382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
639bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMix_class {
640bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface mOutputMix;
644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface mOutputMixExt;
646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
647bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface mVolume;
652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
657bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct VibraDevice_class {
658bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Vibra_interface mVibra;
662bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //
663bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mDeviceID;
664bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
665bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Private functions */
667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
66829b9008a17cae003590a5ff361e98809f02e3025Glenn Kastenstatic void object_lock_exclusive(struct Object_interface *this)
66929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten{
67029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int ok;
67129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    ok = pthread_mutex_lock(&this->mMutex);
67229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    assert(0 == ok);
67329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten}
67429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
67529b9008a17cae003590a5ff361e98809f02e3025Glenn Kastenstatic void object_unlock_exclusive(struct Object_interface *this)
67629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten{
67729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int ok;
67829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    ok = pthread_mutex_unlock(&this->mMutex);
67929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    assert(0 == ok);
68029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten}
68129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
68229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Currently shared locks are implemented as exclusive, but don't count on it
68329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
68429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define object_lock_shared(this)   object_lock_exclusive(this)
68529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define object_unlock_shared(this) object_unlock_exclusive(this)
68629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
68729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Currently interface locks are actually on whole object, but don't count on it
68829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
68929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_lock_exclusive(this)   object_lock_exclusive((this)->mThis)
69029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_unlock_exclusive(this) object_unlock_exclusive((this)->mThis)
69129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_lock_shared(this)      object_lock_shared((this)->mThis)
69229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_unlock_shared(this)    object_unlock_shared((this)->mThis)
69329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
69429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Peek and poke are an optimization for small atomic fields that don't "matter"
69529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
69629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_lock_poke(this)   /* interface_lock_exclusive(this) */
69729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_unlock_poke(this) /* interface_unlock_exclusive(this) */
69829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_lock_peek(this)   /* interface_lock_shared(this) */
69929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#define interface_unlock_peek(this) /* interface_unlock_shared(this) */
70029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
701bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Map SLInterfaceID to its minimal perfect hash (MPH), or -1 if unknown
702bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic int IID_to_MPH(const SLInterfaceID iid)
704d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
705bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid)
706bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return iid - &SL_IID_array[0];
707bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != iid) {
708bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME Replace this linear search by a good MPH algorithm
709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        const struct SLInterfaceID_ *srch = &SL_IID_array[0];
710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        unsigned MPH;
711bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (MPH = 0; MPH < MPH_MAX; ++MPH, ++srch)
712bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (!memcmp(iid, srch, sizeof(struct SLInterfaceID_)))
713bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return MPH;
714bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return -1;
716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
71829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten// Check the interface IDs passed into a Create operation
71929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten
720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult checkInterfaces(const struct class_ *class__,
721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
722bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLboolean *pInterfaceRequired, unsigned *pExposedMask)
723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
724bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(NULL != class__ && NULL != pExposedMask);
725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask = 0;
726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *interfaces = class__->mInterfaces;
727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 interfaceCount = class__->mInterfaceCount;
728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 i;
729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME This section could be pre-computed per class
730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    for (i = 0; i < interfaceCount; ++i) {
731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        switch (interfaces[i].mInterface) {
732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        case INTERFACE_IMPLICIT:
733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            exposedMask |= 1 << i;
734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            break;
735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        default:
736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            break;
737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
739d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (0 < numInterfaces) {
740d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == pInterfaceIds || NULL == pInterfaceRequired)
741d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
742d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        for (i = 0; i < numInterfaces; ++i) {
743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLInterfaceID iid = pInterfaceIds[i];
744bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (NULL == iid)
745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
74629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            int MPH, index;
74729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            if ((0 > (MPH = IID_to_MPH(iid))) ||
74829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                (0 > (index = class__->mMPH_to_index[MPH]))) {
749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                if (pInterfaceRequired[i])
750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    return SL_RESULT_FEATURE_UNSUPPORTED;
751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                continue;
752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
75329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // FIXME this seems a bit strong? what is correct logic?
75429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // we are requesting a duplicate explicit interface,
75529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // or we are requesting one which is already implicit ?
75629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // if (exposedMask & (1 << index))
75729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            //    return SL_RESULT_PARAMETER_INVALID;
75829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            exposedMask |= (1 << index);
759d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
760d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pExposedMask = exposedMask;
762d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
763d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
764d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface initialization hooks */
766d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
767d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SL3DCommitItf_ _3DCommit_3DCommitItf;
768d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DCommit_init(void *self)
770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface *this = (struct _3DCommit_interface *) self;
772bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &_3DCommit_3DCommitItf;
773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDeferred = SL_BOOLEAN_FALSE;
775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
777d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DDoppler_init(void *self)
779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DDoppler_interface *this =
781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DDoppler_interface *) self;
782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
783d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DGrouping_init(void *self)
785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DGrouping_interface *this =
787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DGrouping_interface *) self;
788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
789d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DLocation_init(void *self)
791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DLocation_interface *this =
793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DLocation_interface *) self;
794bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
795d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DMacroscopic_init(void *self)
797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DMacroscopic_interface *this =
799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DMacroscopic_interface *) self;
800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
801d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DSource_init(void *self)
803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DSource_interface *this =
805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DSource_interface *) self;
806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
807d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
808d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLAudioDecoderCapabilitiesItf_
809d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    AudioDecoderCapabilities_AudioDecoderCapabilitiesItf;
810d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioDecoderCapabilities_init(void *self)
812bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioDecoderCapabilities_interface *this =
814bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioDecoderCapabilities_interface *) self;
815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioDecoderCapabilities_AudioDecoderCapabilitiesItf;
816bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
818d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLAudioEncoderCapabilitiesItf_
819d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    AudioEncoderCapabilities_AudioEncoderCapabilitiesItf;
820d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioEncoderCapabilities_init(void *self)
822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoderCapabilities_interface *this =
824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoderCapabilities_interface *) self;
825bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioEncoderCapabilities_AudioEncoderCapabilitiesItf;
826bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
828bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioEncoder_init(void *self)
829bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct AudioEncoder_interface *this =
831bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct AudioEncoder_interface *) self;
832bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
834d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLAudioIODeviceCapabilitiesItf_
835d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
836d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
837bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioIODeviceCapabilities_init(void *self)
838bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
839bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioIODeviceCapabilities_interface *this =
840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioIODeviceCapabilities_interface *) self;
841bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void BassBoost_init(void *self)
845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
846bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct BassBoost_interface *this =
847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct BassBoost_interface *) self;
848bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
850d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf;
851d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void BufferQueue_init(void *self)
853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
854bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &BufferQueue_BufferQueueItf;
856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
857bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState.count = 0;
858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState.playIndex = 0;
859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
860bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mNumBuffers = 0;
862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mArray = NULL;
863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = NULL;
864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRear = NULL;
865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
868d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf;
869d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DeviceVolume_init(void *self)
871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
872bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
874bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &DeviceVolume_DeviceVolumeItf;
875bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
876d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
877d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLDynamicInterfaceManagementItf_
878d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    DynamicInterfaceManagement_DynamicInterfaceManagementItf;
879d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
880bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DynamicInterfaceManagement_init(void *self)
881d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
883bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
884bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf =
885bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
886bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
887bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAddedMask = 0;
888bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
889bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
890bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
891d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
892d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DynamicSource_init(void *self)
894d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
895bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct DynamicSource_interface *this =
896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct DynamicSource_interface *) self;
897d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
898d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
899bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EffectSend_init(void *self)
900d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct EffectSend_interface *this =
902bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct EffectSend_interface *) self;
903d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
904d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
905d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLEngineItf_ Engine_EngineItf;
906d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Engine_init(void *self)
908d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Engine_interface *this = (struct Engine_interface *) self;
910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Engine_EngineItf;
911d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
912d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
913d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLEngineCapabilitiesItf_
914d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    EngineCapabilities_EngineCapabilitiesItf;
915d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EngineCapabilities_init(void *self)
917d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EngineCapabilities_interface *this =
919bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct EngineCapabilities_interface *) self;
920bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &EngineCapabilities_EngineCapabilitiesItf;
921d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
922d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
923bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EnvironmentalReverb_init(void *self)
924d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
925bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct EnvironmentalReverb_interface *this =
926bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        //(struct EnvironmentalReverb_interface *) self;
927d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
929bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Equalizer_init(void *self)
930d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
931bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Equalizer_interface *this =
932bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Equalizer_interface *) self;
933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
935d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLLEDArrayItf_ LEDArray_LEDArrayItf;
936d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
937bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void LEDArray_init(void *self)
938bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
939bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct LEDArray_interface *this = (struct LEDArray_interface *) self;
940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &LEDArray_LEDArrayItf;
941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
943bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MetaDataExtraction_init(void *self)
944bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
945bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MetaDataExtraction_interface *this =
946bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MetaDataExtraction_interface *) self;
947bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
948bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
949bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MetaDataTraversal_init(void *self)
950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
951bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MetaDataTraversal_interface *this =
952bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MetaDataTraversal_interface *) self;
953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDIMessage_init(void *self)
956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
957bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDIMessage_interface *this =
958bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDIMessage_interface *) self;
959bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
960bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
961bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDIMuteSolo_init(void *self)
962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDIMuteSolo_interface *this =
964bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDIMuteSolo_interface *) self;
965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
967bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDITempo_init(void *self)
968bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
969bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDITempo_interface *this =
970bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDITempo_interface *) self;
971bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
972bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDITime_init(void *self)
974bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
975bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDITime_interface *this =
976bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDITime_interface *) self;
977bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
978bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
979bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MuteSolo_init(void *self)
980bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
981bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MuteSolo_interface *this =
982bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MuteSolo_interface *) self;
983bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PrefetchStatus_init(void *self)
986bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
987bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PrefetchStatus_interface *this =
988bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct PrefetchStatus_interface *) self;
989bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
990bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
991d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLObjectItf_ Object_ObjectItf;
992d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_init(void *self)
994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
995d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Object_ObjectItf;
997d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_UNREALIZED;
998bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
999bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
1000bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
1001bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPriority = 0;
1002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreemptable = SL_BOOLEAN_FALSE;
1003bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
100429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int ok;
100529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    ok = pthread_mutex_init(&this->mMutex, (const pthread_mutexattr_t *) NULL);
100629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    assert(0 == ok);
1007d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1008d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1009d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLOutputMixItf_ OutputMix_OutputMixItf;
1010d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMix_init(void *self)
1012d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface *this = (struct OutputMix_interface *) self;
1014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &OutputMix_OutputMixItf;
101529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mActiveMask = 0;
1018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Track *track = &this->mTracks[0];
1019bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME O(n)
1020bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME magic number
1021bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned i;
1022bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    for (i = 0; i < 32; ++i, ++track)
1023bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        track->mPlay = NULL;
1024bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
102529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#endif
1026d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1027d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1029d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf;
1030d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1031bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMixExt_init(void *self)
1032d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1033bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface *this =
1034bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct OutputMixExt_interface *) self;
1035bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &OutputMixExt_OutputMixExtItf;
1036d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_OUTPUTMIXEXT
1038d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1039bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Pitch_init(void *self)
1040d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1041bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Pitch_interface *this =
1042bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Pitch_interface *) self;
1043d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1044d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1045d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLPlayItf_ Play_PlayItf;
1046d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Play_init(void *self)
1048bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1049bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
1050bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Play_PlayItf;
1051bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState = SL_PLAYSTATE_STOPPED;
1052bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDuration = SL_TIME_UNKNOWN;
1053bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1054bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPosition = (SLmillisecond) 0;
1055bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // this->mPlay.mPositionSamples = 0;
1056bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
1057bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
1058bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEventFlags = 0;
1059bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = 0;
1060bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPositionUpdatePeriod = 0;
1061bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1062bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1063bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1064bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PlaybackRate_init(void *self)
1065bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1066bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PlaybackRate_interface *this =
1067bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct PlaybackRate_interface *) self;
1068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1069bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1070bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PresetReverb_init(void *self)
1071bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1072bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PresetReverb_interface *this =
1073bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        //(struct PresetReverb_interface *) self;
1074bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1075bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1076bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void RatePitch_init(void *self)
1077bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1078bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct RatePitch_interface *this =
1079bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct RatePitch_interface *) self;
1080bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1081bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1082bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Record_init(void *self)
1083bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1084bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Record_interface *this = (struct Record_interface *) self;
1085bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1086bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1087d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLSeekItf_ Seek_SeekItf;
1088d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1089bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Seek_init(void *self)
1090bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1091bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
1092bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Seek_SeekItf;
1093bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPos = (SLmillisecond) -1;
1094bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStartPos = (SLmillisecond) -1;
1095bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEndPos = (SLmillisecond) -1;
1096bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1097bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLoopEnabled = SL_BOOLEAN_FALSE;
1098bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1099bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1101d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf;
1102d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void ThreadSync_init(void *self)
1104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1105bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct ThreadSync_interface *this =
1106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct ThreadSync_interface *) self;
1107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &ThreadSync_ThreadSyncItf;
1108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Virtualizer_init(void *self)
1111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Virtualizer_interface *this =
1113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Virtualizer_interface *) self;
1114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1116d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLVibraItf_ Vibra_VibraItf;
1117d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1118bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Vibra_init(void *self)
1119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Vibra_interface *this = (struct Vibra_interface *) self;
1121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Vibra_VibraItf;
1122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1124d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLVisualizationItf_ Visualization_VisualizationItf;
1125d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Visualization_init(void *self)
1127bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1128bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface *this =
1129bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Visualization_interface *) self;
1130bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Visualization_VisualizationItf;
1131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
1133bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
1134bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRate = 0;
1135bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1136bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1138d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenextern const struct SLVolumeItf_ Volume_VolumeItf;
1139d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
1140bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Volume_init(void *self)
1141bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1142bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
1143bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Volume_VolumeItf;
1144bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1145bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLevel = 0; // FIXME correct ?
1146bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMute = SL_BOOLEAN_FALSE;
1147bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnableStereoPosition = SL_BOOLEAN_FALSE;
1148bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStereoPosition = 0;
1149bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1150bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1151bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1152bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct MPH_init {
1153bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // unsigned char mMPH;
1154bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mInit;
1155bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mDeinit;
1156bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} MPH_init_table[MPH_MAX] = {
1157bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DCOMMIT, */ _3DCommit_init, NULL },
1158bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DDOPPLER, */ _3DDoppler_init, NULL },
1159bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DGROUPING, */ _3DGrouping_init, NULL },
1160bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DLOCATION, */ _3DLocation_init, NULL },
1161bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DMACROSCOPIC, */ _3DMacroscopic_init, NULL },
1162bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DSOURCE, */ _3DSource_init, NULL },
1163bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIODECODERCAPABILITIES, */ AudioDecoderCapabilities_init, NULL },
1164bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOENCODER, */ AudioEncoder_init, NULL },
1165bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOENCODERCAPABILITIES, */ AudioEncoderCapabilities_init, NULL },
1166bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOIODEVICECAPABILITIES, */ AudioIODeviceCapabilities_init,
1167bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL },
1168bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_BASSBOOST, */ BassBoost_init, NULL },
1169bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_BUFFERQUEUE, */ BufferQueue_init, NULL },
1170bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DEVICEVOLUME, */ DeviceVolume_init, NULL },
1171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ DynamicInterfaceManagement_init,
1172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL },
1173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DYNAMICSOURCE, */ DynamicSource_init, NULL },
1174bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_EFFECTSEND, */ EffectSend_init, NULL },
1175bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENGINE, */ Engine_init, NULL },
1176bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENGINECAPABILITIES, */ EngineCapabilities_init, NULL },
1177bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENVIRONMENTALREVERB, */ EnvironmentalReverb_init, NULL },
1178bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_EQUALIZER, */ Equalizer_init, NULL },
1179bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_LED, */ LEDArray_init, NULL },
1180bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_METADATAEXTRACTION, */ MetaDataExtraction_init, NULL },
1181bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_METADATATRAVERSAL, */ MetaDataTraversal_init, NULL },
1182bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDIMESSAGE, */ MIDIMessage_init, NULL },
1183bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDITIME, */ MIDITime_init, NULL },
1184bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDITEMPO, */ MIDITempo_init, NULL },
1185bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDIMUTESOLO, */ MIDIMuteSolo_init, NULL },
1186bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MUTESOLO, */ MuteSolo_init, NULL },
1187bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_NULL, */ NULL, NULL },
1188bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OBJECT, */ Object_init, NULL },
1189bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OUTPUTMIX, */ OutputMix_init, NULL },
1190bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PITCH, */ Pitch_init, NULL },
1191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PLAY, */ Play_init, NULL },
1192bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PLAYBACKRATE, */ PlaybackRate_init, NULL },
1193bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PREFETCHSTATUS, */ PrefetchStatus_init, NULL },
1194bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PRESETREVERB, */ PresetReverb_init, NULL },
1195bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_RATEPITCH, */ RatePitch_init, NULL },
1196bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_RECORD, */ Record_init, NULL },
1197bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_SEEK, */ Seek_init, NULL },
1198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_THREADSYNC, */ ThreadSync_init, NULL },
1199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VIBRA, */ Vibra_init, NULL },
1200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VIRTUALIZER, */ Virtualizer_init, NULL },
1201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VISUALIZATION, */ Visualization_init, NULL },
1202bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VOLUME, */ Volume_init, NULL },
1203bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OUTPUTMIXEXT, */
1204bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1205bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        OutputMixExt_init, NULL
1206bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1207bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL, NULL
1208bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1209bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
1210bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1212bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Classes vs. interfaces */
1213bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1214bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// 3DGroup class
1215bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1216bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable _3DGroup_interfaces[] = {
1217bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1218bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, mObject)},
1219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1220bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, mDynamicInterfaceManagement)},
1221bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_IMPLICIT,
1222bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DLocation)},
1223bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1225bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1226bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DSource)},
1227bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DMacroscopic)},
1229bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1231bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ _3DGroup_class = {
1232bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGroup_interfaces,
1233bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(_3DGroup_interfaces)/sizeof(_3DGroup_interfaces[0]),
1234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_3DGroup,
1235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"3DGroup",
1236bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct _3DGroup_class),
1237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_3DGROUP,
1238bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1240d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1242bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// AudioPlayer class
1243bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* AudioPlayer private functions */
12452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
12462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
12472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
12482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread
12492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext)
12502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
12512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct SndFile *this = (struct SndFile *) pContext;
12522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result;
12532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) {
1254bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        result = (*caller)->Enqueue(caller, this->mRetryBuffer,
1255bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            this->mRetrySize);
12562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result)
12572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;     // what, again?
12582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
12592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetryBuffer = NULL;
12602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetrySize = 0;
12612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return;
12622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1;
12642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mIs0 ^= SL_BOOLEAN_TRUE;
12652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sf_count_t count;
12662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME magic number
12672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512);
12682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (0 < count) {
12692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 size = count * sizeof(short);
12702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME if we had an internal API, could call this directly
12712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        result = (*caller)->Enqueue(caller, pBuffer, size);
12722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result) {
12732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetryBuffer = pBuffer;
12742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetrySize = size;
12752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;
12762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
12772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
12782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
12802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
12812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLboolean SndFile_IsSupported(const SF_INFO *sfinfo)
12822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
12832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_TYPEMASK) {
12842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_WAV:
12852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_SUBMASK) {
12902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_PCM_16:
12912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->samplerate) {
12962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 44100:
12972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
13002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
13012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->channels) {
13022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 2:
13032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
13042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
13052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
13062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
13072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_BOOLEAN_TRUE;
13082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
13092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1310bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
13112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1312bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult AudioPlayer_Realize(void *self)
1313bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1314bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
1315bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
1316bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // for Android here is where we do setDataSource etc. for MediaPlayer
1317bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_SNDFILE
13182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mPathname) {
13192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SF_INFO sfinfo;
13202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sfinfo.format = 0;
13212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = sf_open(
13222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (const char *) this->mSndFile.mPathname, SFM_READ, &sfinfo);
13232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == this->mSndFile.mSNDFILE) {
13242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_NOT_FOUND;
13252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else if (!SndFile_IsSupported(&sfinfo)) {
13262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            sf_close(this->mSndFile.mSNDFILE);
13272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mSndFile.mSNDFILE = NULL;
13282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_UNSUPPORTED;
13292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else {
133029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // FIXME how do we know this interface is exposed?
1331bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLBufferQueueItf bufferQueue = &this->mBufferQueue.mItf;
13322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME should use a private internal API, and disallow
13332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // application to have access to our buffer queue
13342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME if we had an internal API, could call this directly
133529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // FIXME can't call this directly as we get a double lock
133629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // result = (*bufferQueue)->RegisterCallback(bufferQueue,
133729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            //    SndFile_Callback, &this->mSndFile);
133829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // FIXME so let's inline the code, but this is maintenance risk
133929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // we know we are called by Object_Realize, which holds a lock,
134029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // but if interface lock != object lock, need to rewrite this
134129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            struct BufferQueue_interface *thisBQ =
134229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                (struct BufferQueue_interface *) bufferQueue;
134329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            thisBQ->mCallback = SndFile_Callback;
134429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            thisBQ->mContext = &this->mSndFile;
13452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
13462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
1347bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
13482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return result;
13492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
13502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1351bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioPlayer_Destroy(void *self)
13522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
13532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
13542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME stop the player in a way that app can't restart it
1355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Free the buffer queue, if it was larger than typical
1356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != this->mBufferQueue.mArray &&
1357bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray != this->mBufferQueue.mTypical) {
13582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        free(this->mBufferQueue.mArray);
1359bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = NULL;
1360bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
13612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
13622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mSNDFILE) {
13632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sf_close(this->mSndFile.mSNDFILE);
13642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = NULL;
13652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
1366bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
1367bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1368bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1369bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable AudioPlayer_interfaces[] = {
1370bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1371bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mObject)},
1372bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1373bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mDynamicInterfaceManagement)},
1374bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAY, INTERFACE_IMPLICIT,
1375bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPlay)},
1376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1377bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DDoppler)},
1378bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DGROUPING, INTERFACE_GAME,
1379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DGrouping)},
1380bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_GAME,
1381bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DLocation)},
1382bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1383bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DSource)},
1384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Currently we create an internal buffer queue for playing files
1385bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BUFFERQUEUE, /* INTERFACE_GAME */ INTERFACE_IMPLICIT,
1386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mBufferQueue)},
1387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EFFECTSEND, INTERFACE_MUSIC_GAME,
1388bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEffectSend)},
1389bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MUTESOLO, INTERFACE_GAME,
1390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMuteSolo)},
1391bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_MUSIC_GAME,
1392bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMetaDataExtraction)},
1393bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_MUSIC_GAME,
1394bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMetaDataTraversal)},
1395bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PREFETCHSTATUS, INTERFACE_TBD,
1396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPrefetchStatus)},
1397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_RATEPITCH, INTERFACE_DYNAMIC_GAME,
1398bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mRatePitch)},
1399bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_SEEK, INTERFACE_TBD,
1400bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mSeek)},
1401bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_TBD,
1402bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVolume)},
1403bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1404bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DMacroscopic)},
1405bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1406bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mBassBoost)},
1407bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1408bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mDynamicSource)},
1409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL,
1410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEnvironmentalReverb)},
1411bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1412bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEqualizer)},
1413bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PITCH, INTERFACE_OPTIONAL,
1414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPitch)},
1415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_OPTIONAL,
1416bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPresetReverb)},
1417bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL,
1418bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPlaybackRate)},
1419bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_OPTIONAL,
1420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVirtualizer)},
1421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVisualization)}
1423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1424bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ AudioPlayer_class = {
1426bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_interfaces,
1427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(AudioPlayer_interfaces)/sizeof(AudioPlayer_interfaces[0]),
1428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_AudioPlayer,
1429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"AudioPlayer",
1430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct AudioPlayer_class),
1431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_AUDIOPLAYER,
1432bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_Realize,
143329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL /*AudioPlayer_Resume*/,
1434bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_Destroy
1435bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// AudioRecorder class
1438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1439bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable AudioRecorder_interfaces[] = {
1440bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mObject)},
1442bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1443bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mDynamicInterfaceManagement)},
1444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_RECORD, INTERFACE_IMPLICIT,
1445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mRecord)},
1446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOENCODER, INTERFACE_TBD,
1447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mAudioEncoder)},
1448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mBassBoost)},
1450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1451bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mDynamicSource)},
1452bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1453bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mEqualizer)},
1454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mVisualization)},
1456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_OPTIONAL,
1457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mVolume)}
1458bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1459bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ AudioRecorder_class = {
1461bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioRecorder_interfaces,
1462bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(AudioRecorder_interfaces)/sizeof(AudioRecorder_interfaces[0]),
1463bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_AudioRecorder,
1464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"AudioRecorder",
1465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct AudioRecorder_class),
1466bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_AUDIORECORDER,
1467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
146829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1471bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Engine class
1473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable Engine_interfaces[] = {
1475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mObject)},
1477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1478bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mDynamicInterfaceManagement)},
1479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENGINE, INTERFACE_IMPLICIT,
1480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mEngine)},
1481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENGINECAPABILITIES, INTERFACE_IMPLICIT,
1482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mEngineCapabilities)},
1483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_THREADSYNC, INTERFACE_IMPLICIT,
1484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mThreadSync)},
1485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOIODEVICECAPABILITIES, INTERFACE_IMPLICIT,
1486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioIODeviceCapabilities)},
1487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIODECODERCAPABILITIES, INTERFACE_EXPLICIT,
1488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioDecoderCapabilities)},
1489bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOENCODERCAPABILITIES, INTERFACE_EXPLICIT,
1490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioEncoderCapabilities)},
1491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DCOMMIT, INTERFACE_EXPLICIT_GAME,
1492bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, m3DCommit)},
1493bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DEVICEVOLUME, INTERFACE_OPTIONAL,
1494bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mDeviceVolume)}
1495bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1496bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1497bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ Engine_class = {
1498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Engine_interfaces,
1499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]),
1500bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Engine,
1501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"Engine",
1502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct Engine_class),
1503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_ENGINE,
1504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
150529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1509bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// LEDDevice class
1510bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable LEDDevice_interfaces[] = {
1512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mObject)},
1514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mDynamicInterfaceManagement)},
1516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_LED, INTERFACE_IMPLICIT,
1517bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mLED)}
1518bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1519bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ LEDDevice_class = {
1521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDDevice_interfaces,
1522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(LEDDevice_interfaces)/sizeof(LEDDevice_interfaces[0]),
1523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_LEDDevice,
1524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"LEDDevice",
1525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct LEDDevice_class),
1526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_LEDDEVICE,
1527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
152829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1530bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Listener class
1533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable Listener_interfaces[] = {
1535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1536bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Listener_class, mObject)},
1537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Listener_class, mDynamicInterfaceManagement)},
1539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_EXPLICIT_GAME,
1542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DLocation)}
1543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1544bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ Listener_class = {
1546bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Listener_interfaces,
1547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(Listener_interfaces)/sizeof(Listener_interfaces[0]),
1548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Listener,
1549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"Listener",
1550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct Listener_class),
1551bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_LISTENER,
1552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
155329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1554bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1557bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// MetadataExtractor class
1558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1559bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable MetadataExtractor_interfaces[] = {
1560bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1561bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mObject)},
1562bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mDynamicInterfaceManagement)},
1564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_IMPLICIT,
1565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mDynamicSource)},
1566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_IMPLICIT,
1567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mMetaDataExtraction)},
1568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_IMPLICIT,
1569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mMetaDataTraversal)}
1570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1572bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ MetadataExtractor_class = {
1573bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtractor_interfaces,
1574bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(MetadataExtractor_interfaces) /
1575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        sizeof(MetadataExtractor_interfaces[0]),
1576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_MetadataExtractor,
1577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"MetadataExtractor",
1578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct MetadataExtractor_class),
1579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_METADATAEXTRACTOR,
1580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
158129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1584bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// MidiPlayer class
1586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable MidiPlayer_interfaces[] = {
1588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mObject)},
1590bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1591bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mDynamicInterfaceManagement)},
1592bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAY, INTERFACE_IMPLICIT,
1593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPlay)},
1594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DGROUPING, INTERFACE_GAME,
1597bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DGrouping)},
1598bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_GAME,
1599bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DLocation)},
1600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1601bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DSource)},
1602bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BUFFERQUEUE, INTERFACE_GAME,
1603bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mBufferQueue)},
1604bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EFFECTSEND, INTERFACE_GAME,
1605bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEffectSend)},
1606bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MUTESOLO, INTERFACE_GAME,
1607bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMuteSolo)},
1608bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_GAME,
1609bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMetaDataExtraction)},
1610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_GAME,
1611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMetaDataTraversal)},
1612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDIMESSAGE, INTERFACE_PHONE_GAME,
1613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDIMessage)},
1614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDITIME, INTERFACE_PHONE_GAME,
1615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDITime)},
1616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDITEMPO, INTERFACE_PHONE_GAME,
1617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDITempo)},
1618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDIMUTESOLO, INTERFACE_GAME,
1619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDIMuteSolo)},
1620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PREFETCHSTATUS, INTERFACE_PHONE_GAME,
1621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPrefetchStatus)},
1622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_SEEK, INTERFACE_PHONE_GAME,
1623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mSeek)},
1624bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_PHONE_GAME,
1625bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVolume)},
1626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DMacroscopic)},
1628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1629bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mBassBoost)},
1630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mDynamicSource)},
1632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL,
1633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEnvironmentalReverb)},
1634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEqualizer)},
1636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PITCH, INTERFACE_OPTIONAL,
1637bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPitch)},
1638bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_OPTIONAL,
1639bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPresetReverb)},
1640bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL,
1641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPlaybackRate)},
1642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_OPTIONAL,
1643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVirtualizer)},
1644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVisualization)}
1646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1647bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ MidiPlayer_class = {
1649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MidiPlayer_interfaces,
1650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(MidiPlayer_interfaces)/sizeof(MidiPlayer_interfaces[0]),
1651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_MidiPlayer,
1652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"MidiPlayer",
1653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct MidiPlayer_class),
1654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_MIDIPLAYER,
1655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
165629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1657bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1658bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// OutputMix class
1661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1662bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable OutputMix_interfaces[] = {
1663bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1664bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mObject)},
1665bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mDynamicInterfaceManagement)},
1667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIX, INTERFACE_IMPLICIT,
1668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mOutputMix)},
1669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1670bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIXEXT, INTERFACE_IMPLICIT,
1671bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mOutputMixExt)},
1672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1673bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIXEXT, INTERFACE_TBD /*NOT AVAIL*/, 0},
1674bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_DYNAMIC_GAME,
1676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mEnvironmentalReverb)},
1677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME,
1678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mEqualizer)},
1679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_DYNAMIC_MUSIC,
1680bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mPresetReverb)},
1681bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME,
1682bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVirtualizer)},
1683bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_GAME_MUSIC,
1684bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVolume)},
1685bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL_DYNAMIC,
1686bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mBassBoost)},
1687bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1688bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVisualization)}
1689bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1690bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1691bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ OutputMix_class = {
1692bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMix_interfaces,
1693bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(OutputMix_interfaces)/sizeof(OutputMix_interfaces[0]),
1694bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_OutputMix,
1695bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"OutputMix",
1696bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct OutputMix_class),
1697bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_OUTPUTMIX,
1698bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
169929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1700bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1701bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1702bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Vibra class
1704bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1705bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable VibraDevice_interfaces[] = {
1706bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_OPTIONAL,
1707bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mObject)},
1708bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_OPTIONAL,
1709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mDynamicInterfaceManagement)},
1710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIBRA, INTERFACE_OPTIONAL,
1711bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mVibra)}
1712bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1713bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1714bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ VibraDevice_class = {
1715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VibraDevice_interfaces,
1716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(VibraDevice_interfaces)/sizeof(VibraDevice_interfaces[0]),
1717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Vibra,
1718bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"VibraDevice",
1719bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct VibraDevice_class),
1720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_VIBRADEVICE,
1721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
172229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    NULL,
1723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1724bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Map SL_OBJECTID to class */
1727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ * const classes[] = {
1729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Do not change order of these entries; they are in numerical order
1730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &Engine_class,
1731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &LEDDevice_class,
1732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &AudioPlayer_class,
1733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &AudioRecorder_class,
1734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &MidiPlayer_class,
1735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &Listener_class,
1736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &_3DGroup_class,
1737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &VibraDevice_class,
1738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &OutputMix_class,
1739bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &MetadataExtractor_class
1740bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1741bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1742bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ *objectIDtoClass(SLuint32 objectID)
1743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1744bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 objectID0 = classes[0]->mObjectID;
1745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (objectID0 <= objectID &&
1746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        classes[sizeof(classes)/sizeof(classes[0])-1]->mObjectID >= objectID)
1747bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return classes[objectID - objectID0];
1748bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return NULL;
1749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Construct a new instance of the specified class, exposing selected interfaces
1752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
175329b9008a17cae003590a5ff361e98809f02e3025Glenn Kastenstatic struct Object_interface *construct(const struct class_ *class__,
175429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned exposedMask, SLEngineItf engine)
1755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
175629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *this;
1757bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
175829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    this = (struct Object_interface *) malloc(class__->mSize);
1759bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
176029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    this = (struct Object_interface *) calloc(1, class__->mSize);
1761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != this) {
1763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // for debugging, to detect uninitialized fields
1765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        memset(this, 0x55, class__->mSize);
1766bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
176729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mClass = class__;
176829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mExposedMask = exposedMask;
176929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        struct Engine_interface *thisEngine =
177029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (struct Engine_interface *) engine;
177129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mLossOfControlMask = (NULL == thisEngine) ? 0 :
177229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (thisEngine->mLossOfControlGlobal ? ~0 : 0);
1773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        const struct iid_vtable *x = class__->mInterfaces;
1774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        unsigned i;
1775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (i = 0; exposedMask; ++i, ++x, exposedMask >>= 1) {
1776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (exposedMask & 1) {
1777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                unsigned MPH = x->mMPH;
1778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                size_t offset = x->mOffset;
1779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                void *self = (char *) this + offset;
1780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                ((void **) self)[1] = this;
1781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                VoidHook init = MPH_init_table[MPH].mInit;
1782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                if (NULL != init)
1783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    (*init)(self);
1784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
1785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
1786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
1787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return this;
1788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface implementations */
1791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME Sort by interface
1793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1794bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Object implementation */
1795bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_Realize(SLObjectItf self, SLboolean async)
1797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = this->mClass;
1800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    StatusHook realize = class__->mRealize;
180129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
180229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(this);
180329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME The realize hook and callback should be asynchronous if requested
180429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (SL_OBJECT_STATE_UNREALIZED != this->mState) {
180529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
180629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    } else {
180729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (NULL != realize)
180829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            result = (*realize)(this);
180929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (SL_RESULT_SUCCESS == result)
181029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            this->mState = SL_OBJECT_STATE_REALIZED;
181129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        // FIXME callback should not run with mutex lock
181229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (async && (NULL != this->mCallback))
181329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (*this->mCallback)(self, this->mContext,
181429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mState, NULL);
181529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
181629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(this);
1817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return result;
1818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_Resume(SLObjectItf self, SLboolean async)
1821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
182229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
182329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    const struct class_ *class__ = this->mClass;
182429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    StatusHook resume = class__->mResume;
182529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
182629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(this);
182729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME The resume hook and callback should be asynchronous if requested
182829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (SL_OBJECT_STATE_SUSPENDED != this->mState) {
182929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
183029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    } else {
183129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (NULL != resume)
183229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            result = (*resume)(this);
183329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (SL_RESULT_SUCCESS == result)
183429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            this->mState = SL_OBJECT_STATE_REALIZED;
183529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        // FIXME callback should not run with mutex lock
183629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (async && (NULL != this->mCallback))
183729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (*this->mCallback)(self, this->mContext,
183829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mState, NULL);
183929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
184029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(this);
184129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    return result;
1842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1843bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetState(SLObjectItf self, SLuint32 *pState)
1845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1846bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pState)
1847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1848bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
184929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Investigate what it would take to change to a peek lock
185029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_shared(this);
185129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLuint32 state = this->mState;
185229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_shared(this);
185329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pState = state;
1854bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1857bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetInterface(SLObjectItf self, const SLInterfaceID iid,
1858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *pInterface)
1859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
186029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (NULL == pInterface)
1861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
186229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result;
186329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    void *interface = NULL;
186429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (NULL == iid)
186529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
186629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    else {
186729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        struct Object_interface *this = (struct Object_interface *) self;
186829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        const struct class_ *class__ = this->mClass;
186929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        int MPH, index;
187029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if ((0 > (MPH = IID_to_MPH(iid))) ||
187129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (0 > (index = class__->mMPH_to_index[MPH])))
187229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            result = SL_RESULT_FEATURE_UNSUPPORTED;
187329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        else {
187429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            unsigned mask = 1 << index;
187529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            object_lock_shared(this);
187629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            if (SL_OBJECT_STATE_REALIZED != this->mState)
187729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                result = SL_RESULT_PRECONDITIONS_VIOLATED;
187829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            else if (!(this->mExposedMask & mask))
187929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                result = SL_RESULT_FEATURE_UNSUPPORTED;
188029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            else {
188129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                // FIXME Should note that interface has been gotten,
188229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                // so as to detect use of ill-gotten interfaces; be sure
188329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                // to change the lock to exclusive if that is done
188429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                interface = (char *) this + class__->mInterfaces[index].mOffset;
188529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                result = SL_RESULT_SUCCESS;
188629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            }
188729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            object_unlock_shared(this);
188829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        }
188929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
189029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *(void **)pInterface = interface;
1891bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1892bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1894bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_RegisterCallback(SLObjectItf self,
1895bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slObjectCallback callback, void *pContext)
1896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1897bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
189829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
189929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(this);
1900bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
1901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
190229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(this);
1903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1904bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_AbortAsyncOperation(SLObjectItf self)
1907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
190829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Asynchronous operations are not yet implemented
1909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1911bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_Destroy(SLObjectItf self)
1912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1913bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_AbortAsyncOperation(self);
1914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = this->mClass;
1916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook destroy = class__->mDestroy;
191729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    const struct iid_vtable *x = class__->mInterfaces;
191829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(this);
191929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // Call the deinitializer for each currently exposed interface,
192029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // whether it is implicit, explicit, optional, or dynamically added.
192129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned exposedMask = this->mExposedMask;
192229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    for ( ; exposedMask; exposedMask >>= 1, ++x) {
192329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (exposedMask & 1) {
192429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            VoidHook deinit = MPH_init_table[x->mMPH].mDeinit;
192529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            if (NULL != deinit)
192629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                (*deinit)((char *) this + x->mOffset);
192729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        }
192829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
1929bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != destroy)
1930bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*destroy)(this);
193129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED;
193229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(this);
1933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
193429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    memset(this, 0x55, class__->mSize);
19352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
19362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    free(this);
19372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1939bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_SetPriority(SLObjectItf self, SLint32 priority,
1940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean preemptable)
1941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
194329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(this);
1944bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPriority = priority;
1945bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreemptable = preemptable;
194629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(this);
1947bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1948bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1949bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetPriority(SLObjectItf self, SLint32 *pPriority,
1951bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pPreemptable)
1952bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pPriority || NULL == pPreemptable)
1954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
195629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_shared(this);
195729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLint32 priority = this->mPriority;
195829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLboolean preemptable = this->mPreemptable;
195929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_shared(this);
196029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pPriority = priority;
196129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pPreemptable = preemptable;
1962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1964bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_SetLossOfControlInterfaces(SLObjectItf self,
1966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled)
1967bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
196829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (0 < numInterfaces) {
196929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        SLuint32 i;
197029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (NULL == pInterfaceIDs)
197129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            return SL_RESULT_PARAMETER_INVALID;
197229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        struct Object_interface *this = (struct Object_interface *) self;
197329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        const struct class_ *class__ = this->mClass;
197429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        unsigned lossOfControlMask = 0;
197529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        // FIXME The cast is due to a typo in the spec
197629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        for (i = 0; i < (SLuint32) numInterfaces; ++i) {
197729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            SLInterfaceID iid = pInterfaceIDs[i];
197829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            if (NULL == iid)
197929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
198029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            int MPH, index;
198129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            if (0 <= (MPH = IID_to_MPH(iid)) &&
198229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                (0 <= (index = class__->mMPH_to_index[MPH])))
198329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                lossOfControlMask |= (1 << index);
198429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        }
198529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        object_lock_exclusive(this);
198629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (enabled)
198729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            this->mLossOfControlMask |= lossOfControlMask;
198829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        else
198929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            this->mLossOfControlMask &= ~lossOfControlMask;
199029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        object_unlock_exclusive(this);
199129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
1992bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1995bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLObjectItf_ Object_ObjectItf = {
1996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Realize,
19972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_Resume,
19982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetState,
19992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetInterface,
20002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_RegisterCallback,
20012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_AbortAsyncOperation,
2002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Destroy,
20032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetPriority,
20042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetPriority,
20052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetLossOfControlInterfaces,
20062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2008d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* DynamicInterfaceManagement implementation */
2009d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2010d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_AddInterface(
2011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLDynamicInterfaceManagementItf self, const SLInterfaceID iid,
2012bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean async)
2013d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == iid)
2015bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
2017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
201829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *thisObject = this->mThis;
2019bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = thisObject->mClass;
202029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int MPH, index;
202129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if ((0 > (MPH = IID_to_MPH(iid))) ||
202229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        (0 > (index = class__->mMPH_to_index[MPH])))
2023bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
202429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result;
202529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    VoidHook init = MPH_init_table[MPH].mInit;
2026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *x = &class__->mInterfaces[index];
2027bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t offset = x->mOffset;
2028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *thisItf = (char *) thisObject + offset;
2029bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ?
2030bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        class__->mSize : x[1].mOffset) - offset;
203129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned mask = 1 << index;
203229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // Lock the object rather than the DIM interface, because
203329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // we modify both the object (exposed) and interface (added)
203429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(thisObject);
203529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (thisObject->mExposedMask & mask) {
203629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
203729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    } else {
203829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        // FIXME Currently do initialization here, but might be asynchronous
2039bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
2040bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// for debugging, to detect uninitialized fields
2041bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define FILLER 0x55
2042bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
2043bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define FILLER 0
2044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
204529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        memset(thisItf, FILLER, size);
204629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        ((void **) thisItf)[1] = thisObject;
204729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (NULL != init)
204829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (*init)(thisItf);
204929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        thisObject->mExposedMask |= mask;
205029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mAddedMask |= mask;
205129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_SUCCESS;
205229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (async && (NULL != this->mCallback)) {
205329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            // FIXME Callback runs with mutex locked
205429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (*this->mCallback)(self, this->mContext,
205529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                SL_DYNAMIC_ITF_EVENT_RESOURCES_AVAILABLE, result, iid);
205629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        }
2057bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
205829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(thisObject);
2059bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return result;
2060d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2061d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2062d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RemoveInterface(
2063bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLDynamicInterfaceManagementItf self, const SLInterfaceID iid)
2064d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2065bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == iid)
2066bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2067bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
2068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
2069bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *thisObject =
207029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        (struct Object_interface *) this->mThis;
2071bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = thisObject->mClass;
2072bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int MPH = IID_to_MPH(iid);
207329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (0 > MPH)
2074bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
2075bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int index = class__->mMPH_to_index[MPH];
207629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (0 > index)
2077bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
207829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
207929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    VoidHook deinit = MPH_init_table[MPH].mDeinit;
2080bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *x = &class__->mInterfaces[index];
2081bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t offset = x->mOffset;
2082bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *thisItf = (char *) thisObject + offset;
2083bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ?
2084bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        class__->mSize : x[1].mOffset) - offset;
208529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned mask = 1 << index;
208629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // Lock the object rather than the DIM interface, because
208729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // we modify both the object (exposed) and interface (added)
208829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(thisObject);
208929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // disallow removal of non-dynamic interfaces
209029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (!(this->mAddedMask & mask)) {
209129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
209229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    } else {
209329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        if (NULL != deinit)
209429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten            (*deinit)(thisItf);
2095bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
209629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        memset(thisItf, 0x55, size);
2097bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
209829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        thisObject->mExposedMask &= ~mask;
209929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mAddedMask &= ~mask;
210029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
210129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(thisObject);
210229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    return result;
2103d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2104d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_ResumeInterface(
2106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
2107d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
2108d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
210929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (NULL == iid)
211029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
211129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
211229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
211329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *thisObject =
211429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        (struct Object_interface *) this->mThis;
211529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    const struct class_ *class__ = thisObject->mClass;
211629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int MPH = IID_to_MPH(iid);
211729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (0 > MPH)
211829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
211929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    int index = class__->mMPH_to_index[MPH];
212029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (0 > index)
212129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
212229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
212329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    unsigned mask = 1 << index;
212429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Change to exclusive when resume hook implemented
212529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_shared(thisObject);
212629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (!(this->mAddedMask & mask))
212729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
212829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Call a resume hook on the interface, if suspended
212929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_shared(thisObject);
213029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    return result;
2131d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2132d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2133d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RegisterCallback(
2134d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
2135d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slDynamicInterfaceManagementCallback callback, void *pContext)
2136d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
2138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
213929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Object_interface *thisObject = this->mThis;
214029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
214129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_lock_exclusive(thisObject);
2142bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
2143bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
214429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    object_unlock_exclusive(thisObject);
2145d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2146d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2147d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2148bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDynamicInterfaceManagementItf_
2149d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenDynamicInterfaceManagement_DynamicInterfaceManagementItf = {
2150d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_AddInterface,
2151d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RemoveInterface,
2152d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_ResumeInterface,
2153d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RegisterCallback
2154d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2155d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2156d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Play implementation */
2157d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2158d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPlayState(SLPlayItf self, SLuint32 state)
2159d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2160d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (state) {
2161d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_STOPPED:
2162d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PAUSED:
2163d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PLAYING:
2164d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
2165d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
2166d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2167d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2168d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
216929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_exclusive(this);
2170d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = state;
21712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_PLAYSTATE_STOPPED == state) {
21722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mPosition = (SLmillisecond) 0;
21732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // this->mPositionSamples = 0;
21742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
217529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_exclusive(this);
2176d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2177d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2178d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2179d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPlayState(SLPlayItf self, SLuint32 *pState)
2180d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2181d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
2182d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2183d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
218429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
218529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLuint32 state = this->mState;
218629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
218729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pState = state;
2188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2189d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2190d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
21912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
2192d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME: for SNDFILE only, check to see if already know duration
21942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // if so, good, otherwise save position,
21952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // read quickly to end of file, counting frames,
21962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // use sample rate to compute duration, then seek back to current position
21972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
21982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
220029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
220129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLmillisecond duration = this->mDuration;
220229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
220329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pMsec = duration;
2204d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
22072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
2208d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
22092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
22102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
221229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
221329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLmillisecond position = this->mPosition;
221429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
221529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pMsec = position;
2216bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME convert sample units to time units
221729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME handle SL_TIME_UNKNOWN
2218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2219d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2220d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2221d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_RegisterCallback(SLPlayItf self, slPlayCallback callback,
2222d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *pContext)
2223d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
222529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
222629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_exclusive(this);
2227bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
2228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
222929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_exclusive(this);
2230d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2232d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2233d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
2234d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
223629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
2237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEventFlags = eventFlags;
223829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2239d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2240d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
22422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetCallbackEventsMask(SLPlayItf self,
22432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pEventFlags)
2244d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2245bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEventFlags)
2246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
224829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
224929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLuint32 eventFlags = this->mEventFlags;
225029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
225129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pEventFlags = eventFlags;
2252d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2253d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2254d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
2256d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2257bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
225829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
2259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = mSec;
226029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2261d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2262d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2263d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2264d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_ClearMarkerPosition(SLPlayItf self)
2265d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
226729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
2268bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = 0;
226929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2270d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2271d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2272d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2273d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
2274d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2275bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMsec)
2276bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2277bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
227829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
227929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLmillisecond markerPosition = this->mMarkerPosition;
228029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
228129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pMsec = markerPosition;
2282d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2285d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
2286d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2287bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
228829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
2289bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPositionUpdatePeriod = mSec;
229029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2291d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2292d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2293d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
22942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPositionUpdatePeriod(SLPlayItf self,
22952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pMsec)
2296d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMsec)
2298bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2299bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
230029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
230129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLmillisecond positionUpdatePeriod = this->mPositionUpdatePeriod;
230229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
230329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pMsec = positionUpdatePeriod;
2304d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2305d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2306d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2307bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPlayItf_ Play_PlayItf = {
2308d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPlayState,
2309d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPlayState,
2310d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetDuration,
2311d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPosition,
2312d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_RegisterCallback,
2313d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetCallbackEventsMask,
2314d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetCallbackEventsMask,
2315d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetMarkerPosition,
2316d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_ClearMarkerPosition,
2317d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetMarkerPosition,
2318d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPositionUpdatePeriod,
2319d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPositionUpdatePeriod
2320d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2321d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2322d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* BufferQueue implementation */
2323d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2324d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer,
2325d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 size)
2326d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2327d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pBuffer)
2328d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2329d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
233029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLresult result;
233129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_exclusive(this);
233229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct BufferHeader *oldRear = this->mRear, *newRear;
233329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if ((newRear = oldRear + 1) == &this->mArray[this->mNumBuffers])
2334d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        newRear = this->mArray;
233529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    if (newRear == this->mFront) {
233629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_BUFFER_INSUFFICIENT;
233729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    } else {
233829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        oldRear->mBuffer = pBuffer;
233929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        oldRear->mSize = size;
234029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        this->mRear = newRear;
234129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        ++this->mState.count;
234229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        result = SL_RESULT_SUCCESS;
234329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    }
234429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_exclusive(this);
234529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    return result;
2346d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2347d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2348d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Clear(SLBufferQueueItf self)
2349d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2350bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
235129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_exclusive(this);
2352bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = &this->mArray[0];
2353bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRear = &this->mArray[0];
235429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    this->mState.count = 0;
235529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_exclusive(this);
2356d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2357d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2358d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
23592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult BufferQueue_GetState(SLBufferQueueItf self,
23602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLBufferQueueState *pState)
2361d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2362d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
2363d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2364d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
236529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLBufferQueueState state;
236629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_shared(this);
236729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#ifdef __cplusplus // FIXME Is this a compiler bug?
236829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    state.count = this->mState.count;
236929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    state.playIndex = this->mState.playIndex;
2370bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
237129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    state = this->mState;
237229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#endif
237329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_shared(this);
237429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#ifdef __cplusplus // FIXME Is this a compiler bug?
237529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    pState->count = state.count;
237629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    pState->playIndex = state.playIndex;
237729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten#else
237829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pState = state;
2379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
2380d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2381d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2382d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2383d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_RegisterCallback(SLBufferQueueItf self,
2384d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback callback, void *pContext)
2385d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2386d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
238729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
238829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_exclusive(this);
2389d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
2390d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
239129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_exclusive(this);
2392d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2393d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2394d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2395bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf = {
2396d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Enqueue,
2397d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Clear,
2398d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_GetState,
2399d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_RegisterCallback
2400d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2401d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2402d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Volume implementation */
2403d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2404d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetVolumeLevel(SLVolumeItf self, SLmillibel level)
2405d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2406d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // stet despite warning because MIN and MAX might change, and because
2407d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // some compilers allow a wider int type to be passed as a parameter
24082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((SL_MILLIBEL_MIN <= level) && (SL_MILLIBEL_MAX >= level)))
2409d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2410d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
241129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
2412d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mLevel = level;
241329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2414d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2415d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2416d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2417d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
2418d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLevel)
24202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
24212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
242229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
242329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLmillibel level = this->mLevel;
242429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
242529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pLevel = level;
2426d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2427d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2428d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
24292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Volume_GetMaxVolumeLevel(SLVolumeItf self,
24302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pMaxLevel)
2431d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMaxLevel)
24332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
24342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMaxLevel = SL_MILLIBEL_MAX;
2435d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2436d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2437d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2438d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetMute(SLVolumeItf self, SLboolean mute)
2439d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
244129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
24422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mMute = mute;
244329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2444d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2445d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2446d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2447d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetMute(SLVolumeItf self, SLboolean *pMute)
2448d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMute)
24502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
24512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
245229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
245329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLboolean mute = this->mMute;
245429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
245529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pMute = mute;
2456d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2457d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2458d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2459d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
2460d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
246229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
24632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEnableStereoPosition = enable;
246429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2465d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2466d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2467d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2468d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_IsEnabledStereoPosition(SLVolumeItf self,
2469d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pEnable)
2470d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEnable)
24722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
24732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
247429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
247529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLboolean enable = this->mEnableStereoPosition;
247629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
247729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pEnable = enable;
2478d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2479d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2480d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2481d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetStereoPosition(SLVolumeItf self,
2482d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille stereoPosition)
2483d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition)))
24852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
248629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
248729b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_poke(this);
24882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStereoPosition = stereoPosition;
248929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_poke(this);
2490d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2491d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2492d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2493d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetStereoPosition(SLVolumeItf self,
2494d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille *pStereoPosition)
2495d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
24962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pStereoPosition)
24972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
24982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
249929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_lock_peek(this);
250029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLpermille stereoPosition = this->mStereoPosition;
250129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    interface_unlock_peek(this);
250229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    *pStereoPosition = stereoPosition;
2503d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2504d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2505d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVolumeItf_ Volume_VolumeItf = {
2507d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetVolumeLevel,
2508d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetVolumeLevel,
2509d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMaxVolumeLevel,
2510d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetMute,
2511d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMute,
2512d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_EnableStereoPosition,
2513d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_IsEnabledStereoPosition,
2514d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetStereoPosition,
2515d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetStereoPosition
2516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2517d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2518d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Engine implementation */
2519d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2520d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice,
2521d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 deviceID, SLuint32 numInterfaces,
25222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2523d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID)
25252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
25262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
2527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&LEDDevice_class, numInterfaces,
2529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
25302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
25312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
253229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct LEDDevice_class *this = (struct LEDDevice_class *)
253329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&LEDDevice_class, exposedMask, self);
25342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
25352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
25362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
2537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDevice = &this->mObject.mItf;
2538d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2539d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2540d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2541d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateVibraDevice(SLEngineItf self,
2542d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces,
2543d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2544d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID)
25462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
25472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
2548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&VibraDevice_class, numInterfaces,
2550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
25512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
25522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
255329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct VibraDevice_class *this = (struct VibraDevice_class *)
255429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&VibraDevice_class, exposedMask, self);
25552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
25562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
25572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
2558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDevice = &this->mObject.mItf;
2559d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2560d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2561d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2562d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_ANDROID
2563d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenstatic void *thread_body(void *arg)
2564d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten{
2565d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) arg;
2566d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    android::AudioTrack *at = this->mAudioTrack;
2567d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#if 1
2568d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    at->start();
2569d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
2570d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    struct BufferQueue_interface *bufferQueue = &this->mBufferQueue;
2571d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    for (;;) {
2572d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        // FIXME replace unsafe polling by a mutex and condition variable
2573d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        struct BufferHeader *oldFront = bufferQueue->mFront;
2574d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        struct BufferHeader *rear = bufferQueue->mRear;
2575d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        if (oldFront == rear) {
2576d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten            usleep(10000);
2577d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten            continue;
2578d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        }
2579d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        struct BufferHeader *newFront = &oldFront[1];
2580d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        if (newFront == &bufferQueue->mArray[bufferQueue->mNumBuffers])
2581d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten            newFront = bufferQueue->mArray;
2582d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        at->write(oldFront->mBuffer, oldFront->mSize);
2583d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        assert(mState.count > 0);
2584d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        --bufferQueue->mState.count;
2585d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        ++bufferQueue->mState.playIndex;
2586d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        bufferQueue->mFront = newFront;
2587d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        slBufferQueueCallback callback = bufferQueue->mCallback;
2588d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        if (NULL != callback) {
2589d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten            (*callback)((SLBufferQueueItf) bufferQueue,
2590d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten                bufferQueue->mContext);
2591d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        }
2592d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    }
2593d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    // unreachable
2594d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    return NULL;
2595d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten}
2596d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
2597d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kastenvoid my_handler(int x, void*y, void*z)
2598d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten{
2599d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten}
2600d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
2601d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten
2602d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
2603d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
2604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2605d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2606d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pPlayer)
2607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2608d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = NULL;
2609bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&AudioPlayer_class, numInterfaces,
2611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
26122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
26132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
2614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // check the audio source and sinks
2615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME move this to a separate function: check source, check locator, etc.
26162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if ((NULL == pAudioSrc) || (NULL == (SLuint32 *) pAudioSrc->pLocator) ||
26172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (NULL == pAudioSrc->pFormat))
2618d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
26192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
26202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
2621d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numBuffers = 0;
26222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataFormat_PCM *df_pcm = NULL;
2623d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_OUTPUTMIXEXT
26242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = NULL;
2625d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
26262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
26272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLchar *pathname = NULL;
2628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
26292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (locatorType) {
2630d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
2631d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
26322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_BufferQueue *dl_bq =
26332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
26342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = dl_bq->numBuffers;
2635d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (0 == numBuffers)
2636d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
26372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
2638d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_PCM:
2639d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            {
26402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
26412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->numChannels) {
2642d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 1:
2643d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 2:
2644d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2645d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2646d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2647d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
26482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->samplesPerSec) {
2649d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 44100:
2650d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 1 // wrong units for samplesPerSec!
2652d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_SAMPLINGRATE_44_1:
2653d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2654d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
2655d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2657d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2658d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
26592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->bitsPerSample) {
2660d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_PCMSAMPLEFORMAT_FIXED_16:
2661d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2662d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2663d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2664d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2665d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
26662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->containerSize) {
2667d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 16:
2668d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2669d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2670d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2672d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
26732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->channelMask) {
2674d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // needs work
2675d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2676d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2677d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
26782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->endianness) {
2679d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_BYTEORDER_LITTLEENDIAN:
2680d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2681d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others esp. big and native (new not in spec)
2682d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2683d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2684d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
2685d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
2686d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            break;
2687d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_MIME:
2688d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_RESERVED3:
2689d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
2690d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        default:
2691d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
2692d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2693d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2694d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
26952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
2696d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
26972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        {
26982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
26992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLchar *uri = dl_uri->URI;
27002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == uri)
27012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_PARAMETER_INVALID;
27022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (strncmp((const char *) uri, "file:///", 8))
27032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
27042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pathname = &uri[8];
27052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
27062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        case SL_DATAFORMAT_MIME:
27072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            {
27082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLDataFormat_MIME *df_mime =
27092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                (SLDataFormat_MIME *) pAudioSrc->pFormat;
27102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLchar *mimeType = df_mime->mimeType;
27112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL == mimeType)
27122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
27132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLuint32 containerType = df_mime->containerType;
27142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!strcmp((const char *) mimeType, "audio/x-wav"))
27152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                ;
27162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // else if (others)
27172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            //    ;
27182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            else
27192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
27202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (containerType) {
27212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            case SL_CONTAINERTYPE_WAV:
27222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                break;
27232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // others
27242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            default:
27252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
27262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
27272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
27282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
27292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        default:
27302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
27312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
27322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME magic number, should be configurable
27332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = 2;
27342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
27352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
2736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
27372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_ADDRESS:
27382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_IODEVICE:
27392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
27402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED5:
27412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
27422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED8:
27432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
2744d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
2745d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2746d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2747bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // check sink, again this should be a separate function
2748d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pAudioSnk || (NULL == (SLuint32 *) pAudioSnk->pLocator))
2749d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2750d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (*(SLuint32 *)pAudioSnk->pLocator) {
2751d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
2752d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
27532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // pAudioSnk->pFormat is ignored
27542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_OutputMix *dl_outmix =
27552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_OutputMix *) pAudioSnk->pLocator;
27562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLObjectItf outputMix = dl_outmix->outputMix;
2757d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME make this an operation on Object: GetClass
27582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if ((NULL == outputMix) || (&OutputMix_class !=
27592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            ((struct Object_interface *) outputMix)->mClass))
2760d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
2761d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_OUTPUTMIXEXT
27622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct OutputMix_interface *om =
27632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            &((struct OutputMix_class *) outputMix)->mOutputMix;
27642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // allocate an entry within OutputMix for this track
27652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME O(n)
27662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned i;
27672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        for (i = 0, track = &om->mTracks[0]; i < 32; ++i, ++track) {
27682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (om->mActiveMask & (1 << i))
27692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
27702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            om->mActiveMask |= 1 << i;
27712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
27722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
27732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (32 <= i) {
27742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME Need a better error code for all slots full in output mix
27752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_MEMORY_FAILURE;
27762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
2777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME replace the above for Android - do not use our own mixer!
2778d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
2779d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2780d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
2781d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
2782d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
2783d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_ADDRESS:
2784d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_IODEVICE:
2785d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED5:
2786d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
2787d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED8:
2788d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
2789d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
2790d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2791d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Construct our new instance
279329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *)
279429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&AudioPlayer_class, exposedMask, self);
27952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
2796d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
27972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME numBuffers is unavailable for URL, must make a default !
2798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(0 < numBuffers);
2799d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mNumBuffers = numBuffers;
2800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // inline allocation of circular mArray, up to a typical max
2801bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (BUFFER_HEADER_TYPICAL >= numBuffers) {
2802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
2803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } else {
2804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME integer overflow possible during multiplication
2805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = (struct BufferHeader *)
2806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            malloc((numBuffers + 1) * sizeof(struct BufferHeader));
2807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        if (NULL == this->mBufferQueue.mArray) {
2808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            free(this);
2809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            return SL_RESULT_MEMORY_FAILURE;
2810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
2811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
2812d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mFront = this->mBufferQueue.mArray;
2813d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mRear = this->mBufferQueue.mArray;
28142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
28152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mPathname = pathname;
28162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mIs0 = SL_BOOLEAN_TRUE;
2817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
2818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mSndFile.mSNDFILE = NULL;
28192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetryBuffer = NULL;
28202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetrySize = 0;
28212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
2822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
2823d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_OUTPUTMIXEXT
2824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // link track to player (NOT for Android!!)
28252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mDfPcm = df_pcm;
28262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mBufferQueue = &this->mBufferQueue;
2827bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    track->mPlay = &this->mPlay;
2828bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // next 2 fields must be initialized explicitly (not part of this)
28292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mReader = NULL;
28302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mAvail = 0;
2831d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
2832d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#ifdef USE_ANDROID
2833d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    this->mAudioTrack = new android::AudioTrack(
283429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        android::AudioSystem::MUSIC,            // streamType
283529b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        44100,                                  // sampleRate
283629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        android::AudioSystem::PCM_16_BIT,       // format
2837d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        // FIXME should be stereo, but mono gives more audio output for testing
283829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        android::AudioSystem::CHANNEL_OUT_MONO, // channels
283929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        256 * 20,                               // frameCount
284029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        0,                                      // flags
284129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        /*NULL*/ my_handler,                    // cbf (callback)
284229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        (void *) self,                          // user
284329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        256 * 20);                              // notificationFrame
2844d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    assert(this->mAudioTrack != NULL);
2845d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    // FIXME should call checkStatus after new
2846d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    int ok;
2847d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    // should happen at Realize, not now
2848d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    ok = pthread_create(&this->mThread, (const pthread_attr_t *) NULL,
2849d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten        thread_body, this);
2850d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten    assert(ok == 0);
2851d20441ee29747b206cb0d197260c3ac78d7762daGlenn Kasten#endif
28522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new audio player object
2853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPlayer = &this->mObject.mItf;
2854d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2855d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2856d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2857d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioRecorder(SLEngineItf self,
2858d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk,
2859d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2860d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2861d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pRecorder)
2863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pRecorder = NULL;
2865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&AudioRecorder_class, numInterfaces,
2867bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2868bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2869bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2870d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2871d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2872d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2873d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
2874d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
2875d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
2876d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2877d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
28782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pPlayer)
28792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
28802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pPlayer = NULL;
2881bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&MidiPlayer_class, numInterfaces,
2883bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
28842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
28852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
28862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMIDISrc || NULL == pAudioOutput)
28872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
288829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct MidiPlayer_class *this = (struct MidiPlayer_class *)
288929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&MidiPlayer_class, exposedMask, self);
28902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
28912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
28922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new MIDI player object
2893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPlayer = &this->mObject.mItf;
2894d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2895d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2896d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2897d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
2898d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2899d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2900d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pListener)
2902bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pListener = NULL;
2904bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&Listener_class, numInterfaces,
2906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2908bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2910d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2911d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2912d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup,
2913d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2914d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2915d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pGroup)
2917bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pGroup = NULL;
2919bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2920bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&_3DGroup_class, numInterfaces,
2921bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2922bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2923bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2924bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2925d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2926d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2927d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix,
2928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2929d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2930d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2931d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pMix)
2932d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMix = NULL;
2934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&OutputMix_class, numInterfaces,
2936bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2937d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
2938d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
293929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct OutputMix_class *this = (struct OutputMix_class *)
294029b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&OutputMix_class, exposedMask, self);
2941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
2942d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
2943bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMix = &this->mObject.mItf;
2944d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2945d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2946d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2947d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMetadataExtractor(SLEngineItf self,
2948d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource,
2949d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2950d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2952bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMetadataExtractor)
2953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMetadataExtractor = NULL;
2955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&MetadataExtractor_class, numInterfaces,
2957bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2958bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2959bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2960bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetadataExtractor_class *this = (struct MetadataExtractor_class *)
296129b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&MetadataExtractor_class, exposedMask, self);
2962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
2963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
2964bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMetadataExtractor = &this->mObject.mItf;
2965d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2966d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2967d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2968d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateExtensionObject(SLEngineItf self,
2969d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pObject, void *pParameters, SLuint32 objectID,
2970d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2971d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2972d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pObject)
2974bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2975bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pObject = NULL;
2976bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2977d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2978d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2979d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedInterfaces(SLEngineItf self,
2980d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
2981d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2982bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumSupportedInterfaces)
2983bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = objectIDtoClass(objectID);
2985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == class__)
2986bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
2987bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumSupportedInterfaces = class__->mInterfaceCount;
2988d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2989d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2990d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2991bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Engine_QuerySupportedInterfaces(SLEngineItf self,
2992d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
2993d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2994d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2995d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2996d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2997d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedExtensions(SLEngineItf self,
2998d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 *pNumExtensions)
2999d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
3000bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumExtensions)
3001bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumExtensions = 0;
3003d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
3004d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3005d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3006d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QuerySupportedExtension(SLEngineItf self,
3007d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
3008d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
3009bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // any index >= 0 will be >= number of supported extensions
3010bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_PARAMETER_INVALID;
3011d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3012d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3013d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_IsExtensionSupported(SLEngineItf self,
3014d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLchar *pExtensionName, SLboolean *pSupported)
3015d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
3016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pExtensionName || NULL == pSupported)
3017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_FALSE;
3019d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
3020d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3021d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3022bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEngineItf_ Engine_EngineItf = {
3023d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateLEDDevice,
3024d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateVibraDevice,
3025d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioPlayer,
3026d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioRecorder,
3027d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMidiPlayer,
3028d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateListener,
3029d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_Create3DGroup,
3030d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateOutputMix,
3031d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMetadataExtractor,
3032d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateExtensionObject,
3033d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedInterfaces,
3034d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedInterfaces,
3035d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedExtensions,
3036d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedExtension,
3037d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_IsExtensionSupported
3038d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
3039d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
30402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioIODeviceCapabilities implementation */
3041d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
30422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioInputs(
30432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumInputs,
30442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pInputDeviceIDs)
3045d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
30462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioInputCapabilities(
30502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
30512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioInputDescriptor *pDescriptor)
30522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
30532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
30572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback(
30582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
30592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioInputsChangedCallback callback, void *pContext)
30602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
30612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioOutputs(
30652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumOutputs,
30662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
30672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
30682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumOutputs)
3069d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
30702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pOutputDeviceIDs) {
30712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME should be OEM-configurable
30722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (2 > *pNumOutputs)
30732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_BUFFER_INSUFFICIENT;
30742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[0] = DEVICE_ID_HEADSET;
30752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[1] = DEVICE_ID_HANDSFREE;
30762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
30772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNumOutputs = 2;
30782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioOutputCapabilities(
30822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
30832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioOutputDescriptor *pDescriptor)
30842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
30852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDescriptor)
3086d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
30872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (deviceID) {
30882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME should be OEM-configurable
30892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HEADSET:
30902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_headset;
30912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
30922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HANDSFREE:
30932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_handsfree;
30942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
30952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
30962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_IO_ERROR;
3097d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
3098d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
3099d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3100d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
31012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
31022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback(
31032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
31042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioOutputsChangedCallback callback, void *pContext)
3105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
31062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult
3110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback(
31112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
31122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slDefaultDeviceIDMapChangedCallback callback, void *pContext)
31132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioInputs(
31182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
31192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioInputs, SLuint32 *pAudioInputDeviceIDs)
31202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioOutputs(
31252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
31262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioOutputs, SLuint32 *pAudioOutputDeviceIDs)
31272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetDefaultAudioDevices(
31322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 defaultDeviceID,
31332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioDevices, SLuint32 *pAudioDeviceIDs)
31342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QuerySampleFormatsSupported(
31392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
31402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmilliHertz samplingRate, SLint32 *pSampleFormats,
31412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumOfSampleFormats)
31422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3146bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioIODeviceCapabilitiesItf_
31472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf = {
31482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioInputs,
31492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioInputCapabilities,
31502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback,
31512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioOutputs,
31522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioOutputCapabilities,
31532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback,
31542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback,
31552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioInputs,
31562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioOutputs,
31572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetDefaultAudioDevices,
31582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QuerySampleFormatsSupported
31592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* OutputMix implementation */
31622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_GetDestinationOutputDeviceIDs(SLOutputMixItf self,
31642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten   SLint32 *pNumDevices, SLuint32 *pDeviceIDs)
31652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_RegisterDeviceChangeCallback(SLOutputMixItf self,
31702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slMixDeviceChangeCallback callback, void *pContext)
31712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_ReRoute(SLOutputMixItf self, SLint32 numOutputDevices,
31762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
31772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3181bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLOutputMixItf_ OutputMix_OutputMixItf = {
31822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_GetDestinationOutputDeviceIDs,
31832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_RegisterDeviceChangeCallback,
31842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_ReRoute
31852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Seek implementation */
31882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetPosition(SLSeekItf self, SLmillisecond pos,
31902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 seekMode)
31912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (seekMode) {
31932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_FAST:
31942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_ACCURATE:
31952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
31962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
3197d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
31982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
31992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
32002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPos = pos;
32012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
3202d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3203d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
32042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetLoop(SLSeekItf self, SLboolean loopEnable,
32052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond startPos, SLmillisecond endPos)
3206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
32072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
32082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mLoopEnabled = loopEnable;
32092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStartPos = startPos;
32102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEndPos = endPos;
32112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
32152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pStartPos, SLmillisecond *pEndPos)
32162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos)
3218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
32192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
32202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pLoopEnabled = this->mLoopEnabled;
32212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStartPos = this->mStartPos;
32222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEndPos = this->mEndPos;
32232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
3224d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3225d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3226bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLSeekItf_ Seek_SeekItf = {
32272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetPosition,
32282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetLoop,
32292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_GetLoop
32302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
32322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DCommit implementation */
3233d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
32342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_Commit(SL3DCommitItf self)
3235d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
32362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
3238d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
32392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_SetDeferred(SL3DCommitItf self, SLboolean deferred)
32402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3241bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface *this = (struct _3DCommit_interface *) self;
3242bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDeferred = deferred;
32432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
3244d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
3245d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DCommitItf_ _3DCommit_3DCommitItf = {
32472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_Commit,
32482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_SetDeferred
32492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
32502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DDoppler implementation */
32522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3253bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetVelocityCartesian(SL3DDopplerItf self,
32542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pVelocity)
3255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
3256bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVelocity)
3257bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3258bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
3259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mCartesian = *pVelocity;
32602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
3262d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3263bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetVelocitySpherical(SL3DDopplerItf self,
32642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter speed)
32652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
3267bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mAzimuth = azimuth;
3268bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mElevation = elevation;
3269bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mSpeed = speed;
32702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
3272d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3273bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_GetVelocityCartesian(SL3DDopplerItf self,
32742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pVelocity)
32752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3276bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVelocity)
3277bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3278bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
3279bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pVelocity = this->mVelocity.mCartesian;
32802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3283bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetDopplerFactor(SL3DDopplerItf self,
32842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille dopplerFactor)
32852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3286bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
3287bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDopplerFactor = dopplerFactor;
32882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_GetDopplerFactor(SL3DDopplerItf self,
3292bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pDopplerFactor)
32932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3294bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDopplerFactor)
3295bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
3297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDopplerFactor = this->mDopplerFactor;
32982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3301bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DDopplerItf_ _3DDoppler_3DDopplerItf = {
3302bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetVelocityCartesian,
3303bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetVelocitySpherical,
3304bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_GetVelocityCartesian,
3305bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetDopplerFactor,
3306bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_GetDopplerFactor
33072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
33082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DLocation implementation */
33102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationCartesian(SL3DLocationItf self,
33122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pLocation)
33132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3314bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pLocation)
3315bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3316bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3317bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian = *pLocation;
33182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationSpherical(SL3DLocationItf self,
33222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance)
33232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3324bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mAzimuth = azimuth;
3326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mElevation = elevation;
3327bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mDistance = distance;
33282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
3329d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
33302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement)
33322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3333bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMovement)
3334bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3335bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3336bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.x += pMovement->x;
3337bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.y += pMovement->y;
3338bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.z += pMovement->z;
33392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetLocationCartesian(SL3DLocationItf self,
33432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pLocation)
33442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3345bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pLocation)
3346bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3347bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3348bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pLocation = this->mLocation.mCartesian;
33492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationVectors(SL3DLocationItf self,
33532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pFront, const SLVec3D *pAbove)
33542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pFront || NULL == pAbove)
3356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3357bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3358bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = *pFront;
3359bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAbove = *pAbove;
33602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationAngles(SL3DLocationItf self,
33642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
33652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3366bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3367bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mHeading = heading;
3368bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPitch = pitch;
3369bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRoll = roll;
33702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta,
33742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pAxis)
33752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pAxis)
3377bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetOrientationVectors(SL3DLocationItf self,
33822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pFront, SLVec3D *pUp)
33832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pFront || NULL == pUp)
3385bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pFront = this->mFront;
3388bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pUp = this->mUp;
33892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3392bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DLocationItf_ _3DLocation_3DLocationItf = {
33932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationCartesian,
33942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationSpherical,
33952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Move,
33962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetLocationCartesian,
33972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationVectors,
33982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationAngles,
33992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Rotate,
34002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetOrientationVectors
34012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioDecoderCapabilities implementation */
34042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should build this table from Caps table below
34062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLuint32 Our_Decoder_IDs[] = {
34072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_PCM,
34082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_MP3,
34092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMR,
34102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWB,
34112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWBPLUS,
34122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AAC,
34132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_WMA,
34142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_REAL,
34152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME not in 1.0.1 header file
34162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define SL_AUDIOCODEC_VORBIS   ((SLuint32) 0x00000009)
34172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_VORBIS
34182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define MAX_DECODERS (sizeof(Our_Decoder_IDs) / sizeof(Our_Decoder_IDs[0]))
34202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoders(
34222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 *pNumDecoders,
34232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pDecoderIds)
34242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
34252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumDecoders)
34262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
34272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDecoderIds)
34282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumDecoders = MAX_DECODERS;
34292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    else {
34302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 numDecoders = *pNumDecoders;
34312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (MAX_DECODERS < numDecoders) {
34322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            numDecoders = MAX_DECODERS;
34332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            *pNumDecoders = MAX_DECODERS;
34342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
34352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memcpy(pDecoderIds, Our_Decoder_IDs, numDecoders * sizeof(SLuint32));
34362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
34372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
34382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
34392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLmilliHertz Sample_Rates_PCM[] = {
34412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,
34422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_11_025,
34432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_12,
34442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_16,
34452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_22_05,
34462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_24,
34472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_32,
34482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
34492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48
34502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioCodecDescriptor Caps_PCM[] = {
34532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {
34542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2,                   // maxChannels
34552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    8,                   // minBitsPerSample
34562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    16,                  // maxBitsPerSample
34572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,   // minSampleRate
34582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48,  // maxSampleRate
34592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,    // isFreqRangeContinuous
34602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLmilliHertz *) Sample_Rates_PCM,
34612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // pSampleRatesSupported;
34622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(Sample_Rates_PCM)/sizeof(Sample_Rates_PCM[0]),
34632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // numSampleRatesSupported
34642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    1,                   // minBitRate
34652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ~0,                  // maxBitRate
34662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,     // isBitrateRangeContinuous
34672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,                // pBitratesSupported
34682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,                   // numBitratesSupported
34692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOPROFILE_PCM, // profileSetting
34702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0                    // modeSetting
34712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
34722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct AudioDecoderCapabilities {
34752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mDecoderID;
34762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mNumCapabilities;
34772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLAudioCodecDescriptor *mDescriptors;
34782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten} Our_Decoder_Capabilities[] = {
3479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define ENTRY(x) \
3480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {SL_AUDIOCODEC_##x, sizeof(Caps_##x)/sizeof(Caps_##x[0]), Caps_##x}
34812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(PCM)
34822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#if 0
34832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(MP3),
34842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMR),
34852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWB),
34862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWBPLUS),
34872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AAC),
34882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(WMA),
34892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(REAL),
34902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(VORBIS)
34912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
34922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
34942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoderCapabilities(
34952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 decoderId, SLuint32 *pIndex,
34962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
34972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
34982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
34992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioDecoderCapabilitiesItf_
35022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_AudioDecoderCapabilitiesItf = {
35032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoders,
35042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoderCapabilities
35052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
35062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoder implementation */
35082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_SetEncoderSettings(SLAudioEncoderItf self,
35102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings  *pSettings)
35112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSettings)
3513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoder_interface *this =
3515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoder_interface *) self;
3516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mSettings = *pSettings;
35172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_GetEncoderSettings(SLAudioEncoderItf self,
35212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings *pSettings)
35222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSettings)
3524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoder_interface *this =
3526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoder_interface *) self;
3527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSettings = this->mSettings;
35282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioEncoderItf_ AudioEncoder_AudioEncoderItf = {
35322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_SetEncoderSettings,
35332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_GetEncoderSettings
35342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
35352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoderCapabilities implementation */
35372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoders(
3539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 *pNumEncoders,
3540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEncoderIds)
35412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
35422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoderCapabilities(
35462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 encoderId, SLuint32 *pIndex,
35472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
35482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
35492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioEncoderCapabilitiesItf_
35532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_AudioEncoderCapabilitiesItf = {
35542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoders,
35552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoderCapabilities
35562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
35572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DeviceVolume implementation */
35592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolumeScale(SLDeviceVolumeItf self,
35612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pMinValue, SLint32 *pMaxValue,
35622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsMillibelScale)
35632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
35642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMinValue)
35652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMinValue = 0;
35662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMaxValue)
35672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMaxValue = 10;
35682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsMillibelScale)
35692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsMillibelScale = SL_BOOLEAN_FALSE;
35702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_SetVolume(SLDeviceVolumeItf self,
35742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 volume)
35752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
3577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
3578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVolume = volume;
35792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolume(SLDeviceVolumeItf self,
35832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pVolume)
35842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVolume)
3586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
3588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
3589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pVolume = this->mVolume;
35902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
35912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
35922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf = {
35942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolumeScale,
35952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_SetVolume,
35962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolume
35972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
35982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
35992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DynamicSource implementation */
36002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DynamicSource_SetSource(SLDynamicSourceItf self,
36022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataSource *pDataSource)
36032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3607bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDynamicSourceItf_ DynamicSource_DynamicSourceItf = {
36082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DynamicSource_SetSource
36092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
36102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EffectSend implementation */
36122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_EnableEffectSend(SLEffectSendItf self,
36142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
36152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_IsEnabled(SLEffectSendItf self,
36202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
36212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetDirectLevel(SLEffectSendItf self,
36262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel directLevel)
36272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetDirectLevel(SLEffectSendItf self,
36322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pDirectLevel)
36332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetSendLevel(SLEffectSendItf self,
36382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel sendLevel)
36392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetSendLevel(SLEffectSendItf self,
36442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel *pSendLevel)
36452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEffectSendItf_ EffectSend_EffectSendItf = {
36502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_EnableEffectSend,
36512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_IsEnabled,
36522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetDirectLevel,
36532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetDirectLevel,
36542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetSendLevel,
36552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetSendLevel
36562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
36572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EngineCapabilities implementation */
36592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QuerySupportedProfiles(
36612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported)
36622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pProfilesSupported)
36642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
36652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME This is pessimistic as it omits the unofficial driver profile
3666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // SL_PROFILES_PHONE | SL_PROFILES_MUSIC | SL_PROFILES_GAME
3667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pProfilesSupported = 0;
36682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAvailableVoices(
36722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 voiceType, SLint16 *pNumMaxVoices,
36732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices)
36742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (voiceType) {
36762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_2D_AUDIO:
36772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_MIDI:
36782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_AUDIO:
36792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_MIDIOUTPUT:
36802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
36812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
36822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
36832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
36842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumMaxVoices)
36852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumMaxVoices = 0;
36862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsAbsoluteMax)
36872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsAbsoluteMax = SL_BOOLEAN_TRUE;
36882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumFreeVoices)
36892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumFreeVoices = 0;
36902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
36912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
36922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
36932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryNumberOfMIDISynthesizers(
36942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLint16 *pNum)
36952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
36962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNum)
36972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
36982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNum = 0;
36992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
37002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
37012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
37022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self,
37032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep)
37042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
37052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!(NULL != pMajor && NULL != pMinor && NULL != pStep))
37062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
37072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMajor = 1;
37082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMinor = 0;
37092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStep = 1;
37102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
37112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
37122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
37132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryLEDCapabilities(
37142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pLEDDeviceID,
37152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLLEDDescriptor *pDescriptor)
37162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
37172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
37182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
37192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
37202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryVibraCapabilities(
37212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pVibraDeviceID,
37222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVibraDescriptor *pDescriptor)
37232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
37242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
37252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
37262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
37272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self,
37282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsThreadSafe)
37292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
37302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pIsThreadSafe)
37312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
37322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME For now
37332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pIsThreadSafe = SL_BOOLEAN_FALSE;
37342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
37352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
37362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEngineCapabilitiesItf_
37382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_EngineCapabilitiesItf = {
37392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QuerySupportedProfiles,
37402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAvailableVoices,
37412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryNumberOfMIDISynthesizers,
37422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAPIVersion,
37432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryLEDCapabilities,
37442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryVibraCapabilities,
37452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_IsThreadSafe
37462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
37472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3748bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* LEDArray implementation */
3749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_ActivateLEDArray(SLLEDArrayItf self,
3751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 lightMask)
3752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3753bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3754bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3756bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_IsLEDArrayActivated(SLLEDArrayItf self,
3757bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *lightMask)
3758bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3759bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3760bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_SetColor(SLLEDArrayItf self, SLuint8 index,
3763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLHSL *color)
3764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3766bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3767bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_GetColor(SLLEDArrayItf self, SLuint8 index,
3769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLHSL *color)
3770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3772bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLLEDArrayItf_ LEDArray_LEDArrayItf = {
3775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_ActivateLEDArray,
3776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_IsLEDArrayActivated,
3777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_SetColor,
3778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_GetColor,
3779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MetadataExtraction implementation */
3782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetItemCount(SLMetadataExtractionItf self,
3784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pItemCount)
3785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetKeySize(SLMetadataExtractionItf self,
3790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 *pKeySize)
3791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3794bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3795bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetKey(SLMetadataExtractionItf self,
3796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 keySize, SLMetadataInfo *pKey)
3797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3801bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetValueSize(SLMetadataExtractionItf self,
3802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 *pValueSize)
3803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetValue(SLMetadataExtractionItf self,
3808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 valueSize, SLMetadataInfo *pValue)
3809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3812bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_AddKeyFilter(SLMetadataExtractionItf self,
3814bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 keySize, const void *pKey, SLuint32 keyEncoding,
3815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLchar *pValueLangCountry, SLuint32 valueEncoding, SLuint8 filterMask)
3816bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_ClearKeyFilter(SLMetadataExtractionItf self)
3821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3825bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMetadataExtractionItf_
3826bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_MetadataExtractionItf = {
3827bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetItemCount,
3828bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetKeySize,
3829bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetKey,
3830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetValueSize,
3831bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetValue,
3832bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_AddKeyFilter,
3833bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_ClearKeyFilter
3834bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3835bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3836bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MetadataTraversal implementation */
3837bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3838bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_SetMode(SLMetadataTraversalItf self,
3839bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mode)
3840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3841bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3843bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildCount(SLMetadataTraversalItf self,
3845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pCount)
3846bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3848bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3849bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3850bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildMIMETypeSize(
3851bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLMetadataTraversalItf self, SLuint32 index, SLuint32 *pSize)
3852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3854bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildInfo(SLMetadataTraversalItf self,
3857bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLint32 *pNodeID, SLuint32 *pType, SLuint32 size,
3858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLchar *pMimeType)
3859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3860bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_SetActiveNode(SLMetadataTraversalItf self,
3864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index)
3865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3867bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3868bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3869bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMetadataTraversalItf_
3870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_MetadataTraversalItf = {
3871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_SetMode,
3872bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildCount,
3873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildMIMETypeSize,
3874bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildInfo,
3875bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_SetActiveNode
3876bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3877bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3878bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MuteSolo implementation */
3879bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3880bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan,
3881bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten   SLboolean mute)
3882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3883bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3884bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3885bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3886bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan,
3887bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pMute)
3888bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3889bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3890bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3891bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3892bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
3893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean solo)
3894bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3895bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3897bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3898bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
3899bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSolo)
3900bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3902bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3904bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetNumChannels(SLMuteSoloItf self,
3905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint8 *pNumChannels)
3906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3908bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMuteSoloItf_ MuteSolo_MuteSoloItf = {
3911bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_SetChannelMute,
3912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetChannelMute,
3913bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_SetChannelSolo,
3914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetChannelSolo,
3915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetNumChannels
3916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3917bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Pitch implementation */
3919bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3920bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_SetPitch(SLPitchItf self, SLpermille pitch)
3921bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3922bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3923bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3924bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3925bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_GetPitch(SLPitchItf self, SLpermille *pPitch)
3926bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3927bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3928bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3929bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3930bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_GetPitchCapabilities(SLPitchItf self,
3931bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinPitch, SLpermille *pMaxPitch)
3932bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3936bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPitchItf_ Pitch_PitchItf = {
3937bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_SetPitch,
3938bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_GetPitch,
3939bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_GetPitchCapabilities
3940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* PlaybackRate implementation */
3943bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3944bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate)
3945bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3946bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3947bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3948bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3949bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate)
3950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3951bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3952bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self,
3955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 constraints)
3956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3957bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3958bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3959bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3960bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetProperties(SLPlaybackRateItf self,
3961bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pProperties)
3962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3964bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self,
3967bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille rate, SLuint32 *pCapabilities)
3968bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3969bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3970bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3971bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3972bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index,
3973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize,
3974bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pCapabilities)
3975bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3976bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3977bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3978bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3979bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPlaybackRateItf_ PlaybackRate_PlaybackRateItf = {
3980bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_SetRate,
3981bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetRate,
3982bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_SetPropertyConstraints,
3983bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetProperties,
3984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetCapabilitiesOfRate,
3985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetRateRange
3986bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3987bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3988bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* PrefetchStatus implementation */
3989bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3990bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetPrefetchStatus(SLPrefetchStatusItf self,
3991bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pStatus)
3992bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3995bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetFillLevel(SLPrefetchStatusItf self,
3997bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pLevel)
3998bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3999bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4000bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4001bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_RegisterCallback(SLPrefetchStatusItf self,
4003bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slPrefetchCallback callback, void *pContext)
4004bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4007bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4008bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_SetCallbackEventsMask(SLPrefetchStatusItf self,
4009bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 eventFlags)
4010bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4012bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetCallbackEventsMask(SLPrefetchStatusItf self,
4015bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEventFlags)
4016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4019bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4020bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_SetFillUpdatePeriod(SLPrefetchStatusItf self,
4021bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille period)
4022bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4023bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4024bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4025bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetFillUpdatePeriod(SLPrefetchStatusItf self,
4027bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pPeriod)
4028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4029bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4030bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4031bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4032bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPrefetchStatusItf_
4033bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn KastenPrefetchStatus_PrefetchStatusItf = {
4034bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetPrefetchStatus,
4035bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetFillLevel,
4036bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_RegisterCallback,
4037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_SetCallbackEventsMask,
4038bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetCallbackEventsMask,
4039bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_SetFillUpdatePeriod,
4040bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetFillUpdatePeriod
4041bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4042bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4043bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* RatePitch implementation */
4044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4045bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_SetRate(SLRatePitchItf self, SLpermille rate)
4046bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4048bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4049bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4050bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_GetRate(SLRatePitchItf self, SLpermille *pRate)
4051bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4052bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4053bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4054bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4055bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_GetRatePitchCapabilities(SLRatePitchItf self,
4056bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate)
4057bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4058bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4059bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4060bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4061bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLRatePitchItf_ RatePitch_RatePitchItf = {
4062bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_SetRate,
4063bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_GetRate,
4064bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_GetRatePitchCapabilities
4065bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4066bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4067bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Record implementation */
4068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4069bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetRecordState(SLRecordItf self, SLuint32 state)
4070bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4071bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4072bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4073bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4074bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetRecordState(SLRecordItf self, SLuint32 *pState)
4075bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4076bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4077bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4078bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4079bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetDurationLimit(SLRecordItf self, SLmillisecond msec)
4080bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4081bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4082bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4083bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4084bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetPosition(SLRecordItf self, SLmillisecond *pMsec)
4085bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4086bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4087bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4088bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4089bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_RegisterCallback(SLRecordItf self,
4090bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slRecordCallback callback, void *pContext)
4091bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4092bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4093bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4094bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4095bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetCallbackEventsMask(SLRecordItf self,
4096bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 eventFlags)
4097bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4098bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4099bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4101bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetCallbackEventsMask(SLRecordItf self,
4102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEventFlags)
4103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4105bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetMarkerPosition(SLRecordItf self, SLmillisecond mSec)
4108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_ClearMarkerPosition(SLRecordItf self)
4113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4116bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4117bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec)
4118bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetPositionUpdatePeriod(SLRecordItf self,
4123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mSec)
4124bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4125bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4127bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4128bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetPositionUpdatePeriod(SLRecordItf self,
4129bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond *pMsec)
4130bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4133bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4134bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLRecordItf_ Record_RecordItf = {
4135bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetRecordState,
4136bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetRecordState,
4137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetDurationLimit,
4138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetPosition,
4139bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_RegisterCallback,
4140bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetCallbackEventsMask,
4141bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetCallbackEventsMask,
4142bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetMarkerPosition,
4143bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_ClearMarkerPosition,
4144bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetMarkerPosition,
4145bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetPositionUpdatePeriod,
4146bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetPositionUpdatePeriod
4147bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4148bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4149bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* ThreadSync implementation */
4150bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4151bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult ThreadSync_EnterCriticalSection(SLThreadSyncItf self)
4152bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4153bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4154bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4155bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4156bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult ThreadSync_ExitCriticalSection(SLThreadSyncItf self)
4157bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4158bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4159bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4160bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4161bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf = {
4162bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    ThreadSync_EnterCriticalSection,
4163bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    ThreadSync_ExitCriticalSection
4164bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4165bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4166bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Vibra implementation */
4167bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4168bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_Vibrate(SLVibraItf self, SLboolean vibrate)
4169bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4170bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_IsVibrating(SLVibraItf self, SLboolean *pVibrating)
4174bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4175bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4176bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4177bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4178bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_SetFrequency(SLVibraItf self, SLmilliHertz frequency)
4179bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4180bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4181bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4182bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4183bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_GetFrequency(SLVibraItf self, SLmilliHertz *pFrequency)
4184bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4185bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4186bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4187bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4188bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_SetIntensity(SLVibraItf self, SLpermille intensity)
4189bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4190bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4192bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4193bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_GetIntensity(SLVibraItf self, SLpermille *pIntensity)
4194bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4195bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4196bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4197bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVibraItf_ Vibra_VibraItf = {
4199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_Vibrate,
4200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_IsVibrating,
4201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_SetFrequency,
4202bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_GetFrequency,
4203bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_SetIntensity,
4204bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_GetIntensity
4205bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4206bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4207bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Visualization implementation */
4208bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4209bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Visualization_RegisterVisualizationCallback(
4210bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVisualizationItf self, slVisualizationCallback callback, void *pContext,
4211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz rate)
4212bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4213bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface *this =
4214bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Visualization_interface *) self;
4215bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
4216bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
4217bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRate = rate;
4218bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4220bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4221bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Visualization_GetMaxRate(SLVisualizationItf self,
4222bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pRate)
4223bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pRate)
4225bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4226bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pRate = 0;
4227bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4229bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVisualizationItf_ Visualization_VisualizationItf = {
4231bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Visualization_RegisterVisualizationCallback,
4232bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Visualization_GetMaxRate
4233bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* BassBoost implementation */
42362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_SetEnabled(SLBassBoostItf self, SLboolean enabled)
42382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
4240bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnabled = enabled;
42412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_IsEnabled(SLBassBoostItf self, SLboolean *pEnabled)
42452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEnabled)
4247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
4249bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEnabled = this->mEnabled;
42502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4253bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_SetStrength(SLBassBoostItf self, SLpermille strength)
42542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4255bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
4256bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStrength = strength;
42572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4260bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_GetRoundedStrength(SLBassBoostItf self,
4261bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pStrength)
42622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4263bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pStrength)
4264bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4265bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
4266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pStrength = this->mStrength;
42672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4270bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_IsStrengthSupported(SLBassBoostItf self,
4271bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSupported)
4272bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4273bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSupported)
4274bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4275bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_TRUE;
4276bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4277bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4278bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4279bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLBassBoostItf_ BassBoost_BassBoostItf = {
4280bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_SetEnabled,
4281bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_IsEnabled,
4282bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_SetStrength,
4283bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_GetRoundedStrength,
4284bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_IsStrengthSupported
42852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
42862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4287bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DGrouping implementation */
42882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4289bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DGrouping_Set3DGroup(SL3DGroupingItf self, SLObjectItf group)
42902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self;
4292bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mGroup = group;
42932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DGrouping_Get3DGroup(SL3DGroupingItf self,
4297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLObjectItf *pGroup)
42982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4299bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pGroup)
4300bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4301bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self;
4302bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pGroup = this->mGroup;
43032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4306bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DGroupingItf_ _3DGrouping_3DGroupingItf = {
4307bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGrouping_Set3DGroup,
4308bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGrouping_Get3DGroup
4309bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4310bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4311bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DMacroscopic implementation */
4312bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4313bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetSize(SL3DMacroscopicItf self,
4314bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter width, SLmillimeter height, SLmillimeter depth)
43152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4319bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_GetSize(SL3DMacroscopicItf self,
4320bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter *pWidth, SLmillimeter *pHeight, SLmillimeter *pDepth)
43212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self,
4326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
43272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4331bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self,
4332bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLVec3D *pFront, const SLVec3D *pAbove)
43332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4337bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_Rotate(SL3DMacroscopicItf self,
4338bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree theta, const SLVec3D *pAxis)
43392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4343bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self,
4344bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D *pFront, SLVec3D *pUp)
4345bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4346bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4347bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4348bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4349bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DMacroscopicItf_ _3DMacroscopic_3DMacroscopicItf = {
4350bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetSize,
4351bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_GetSize,
4352bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetOrientationAngles,
4353bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetOrientationVectors,
4354bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_Rotate,
4355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_GetOrientationVectors
43562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
43572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4358bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DSource implementation */
43592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4360bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetHeadRelative(SL3DSourceItf self,
4361bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean headRelative)
43622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4366bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetHeadRelative(SL3DSourceItf self,
4367bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pHeadRelative)
43682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4372bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffDistances(SL3DSourceItf self,
4373bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter minDistance, SLmillimeter maxDistance)
43742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4378bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffDistances(SL3DSourceItf self,
4379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter *pMinDistance, SLmillimeter *pMaxDistance)
43802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self,
4385bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mute)
43862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self,
4391bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pMute)
43922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffFactor(SL3DSourceItf self,
4397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille rolloffFactor)
43982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4402bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffFactor(SL3DSourceItf self,
4403bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pRolloffFactor)
44042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4408bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRoomRolloffFactor(SL3DSourceItf self,
4409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille roomRolloffFactor)
44102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRoomRolloffFactor(SL3DSourceItf self,
4415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pRoomRolloffFactor)
44162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffModel(SL3DSourceItf self, SLuint8 model)
4421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
44242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffModel(SL3DSourceItf self, SLuint8 *pModel)
44262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetCone(SL3DSourceItf self, SLmillidegree innerAngle,
4431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree outerAngle, SLmillibel outerLevel)
44322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetCone(SL3DSourceItf self,
4437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree *pInnerAngle, SLmillidegree *pOuterAngle,
4438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pOuterLevel)
44392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4443bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DSourceItf_ _3DSource_3DSourceItf = {
4444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetHeadRelative,
4445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetHeadRelative,
4446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffDistances,
4447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffDistances,
4448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffMaxDistanceMute,
4449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffMaxDistanceMute,
4450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffFactor,
4451bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffFactor,
4452bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRoomRolloffFactor,
4453bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRoomRolloffFactor,
4454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffModel,
4455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffModel,
4456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetCone,
4457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetCone
44582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
44592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Equalizer implementation */
44612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4462bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
44632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
44682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetNumberOfBands(SLEqualizerItf self,
4473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pNumBands)
44742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4478bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandLevelRange(SLEqualizerItf self,
4479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pMin, SLmillibel *pMax)
44802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_SetBandLevel(SLEqualizerItf self, SLuint16 band,
4485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel level)
44862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandLevel(SLEqualizerItf self, SLuint16 band,
4491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pLevel)
44922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4496bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band,
4497bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pCenter)
44982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
4503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pMin, SLmilliHertz *pMax)
45042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency,
4509bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pBand)
45102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetCurrentPreset(SLEqualizerItf self,
4515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pPreset)
45162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_UsePreset(SLEqualizerItf self, SLuint16 index)
45212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetNumberOfPresets(SLEqualizerItf self,
4526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pNumPresets)
45272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetPresetName(SLEqualizerItf self, SLuint16 index,
4532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLchar ** ppName)
45332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEqualizerItf_ Equalizer_EqualizerItf = {
4538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_SetEnabled,
4539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_IsEnabled,
4540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetNumberOfBands,
4541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandLevelRange,
4542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_SetBandLevel,
4543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandLevel,
4544bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetCenterFreq,
4545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandFreqRange,
4546bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBand,
4547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetCurrentPreset,
4548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_UsePreset,
4549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetNumberOfPresets,
4550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetPresetName
45512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
45522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// PresetReverb implementation
45542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PresetReverb_SetPreset(SLPresetReverbItf self,
4556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 preset)
45572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface *this =
4559bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct PresetReverb_interface *) self;
4560bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreset = preset;
45612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PresetReverb_GetPreset(SLPresetReverbItf self,
4565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pPreset)
45662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pPreset)
4568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface *this =
4570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct PresetReverb_interface *) self;
4571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPreset = this->mPreset;
45722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPresetReverbItf_ PresetReverb_PresetReverbItf = {
4576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PresetReverb_SetPreset,
4577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PresetReverb_GetPreset
45782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
45792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// EnvironmentalReverb implementation
45812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetRoomLevel(SLEnvironmentalReverbItf self,
4583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel room)
45842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetRoomLevel(SLEnvironmentalReverbItf self,
4589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pRoom)
45902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetRoomHFLevel(
4595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel roomHF)
45962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
45982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetRoomHFLevel(
4601bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pRoomHF)
46022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4606bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDecayTime(
4607bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond decayTime)
46082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDecayTime(
4613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pDecayTime)
46142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDecayHFRatio(
4619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille decayHFRatio)
46202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4624bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDecayHFRatio(
4625bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille *pDecayHFRatio)
46262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReflectionsLevel(
4631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel reflectionsLevel)
46322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReflectionsLevel(
4637bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pReflectionsLevel)
46382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReflectionsDelay(
4643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond reflectionsDelay)
46442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReflectionsDelay(
4649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pReflectionsDelay)
46502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReverbLevel(
4655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel reverbLevel)
46562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReverbLevel(
4661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pReverbLevel)
46622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReverbDelay(
4667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond reverbDelay)
4668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4670bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
46712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReverbDelay(
4673bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pReverbDelay)
4674bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
46772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDiffusion(
4679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille diffusion)
46802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4684bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDiffusion(SLEnvironmentalReverbItf self,
4685bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten     SLpermille *pDiffusion)
46862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4690bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDensity(SLEnvironmentalReverbItf self,
4691bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille density)
46922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
46942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4696bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDensity(SLEnvironmentalReverbItf self,
4697bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pDensity)
46982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
47002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
47012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4702bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetEnvironmentalReverbProperties(
4703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self,
4704bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLEnvironmentalReverbSettings *pProperties)
47052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
47062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
47072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
47082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetEnvironmentalReverbProperties(
4710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLEnvironmentalReverbSettings *pProperties)
47112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
47122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
47132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
47142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEnvironmentalReverbItf_
4716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_EnvironmentalReverbItf = {
4717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetRoomLevel,
4718bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetRoomLevel,
4719bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetRoomHFLevel,
4720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetRoomHFLevel,
4721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDecayTime,
4722bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDecayTime,
4723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDecayHFRatio,
4724bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDecayHFRatio,
4725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReflectionsLevel,
4726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReflectionsLevel,
4727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReflectionsDelay,
4728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReflectionsDelay,
4729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReverbLevel,
4730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReverbLevel,
4731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReverbDelay,
4732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReverbDelay,
4733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDiffusion,
4734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDiffusion,
4735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDensity,
4736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDensity,
4737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetEnvironmentalReverbProperties,
4738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetEnvironmentalReverbProperties
47392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
47402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4741bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Virtualizer implementation
47422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_SetEnabled(SLVirtualizerItf self, SLboolean enabled)
47442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnabled = enabled;
47472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
47482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
47492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_IsEnabled(SLVirtualizerItf self,
4751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pEnabled)
47522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4753bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEnabled)
4754bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4756bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEnabled = this->mEnabled;
47572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
47582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
47592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4760bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_SetStrength(SLVirtualizerItf self,
4761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille strength)
4762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStrength = strength;
4765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4766bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4767bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_GetRoundedStrength(SLVirtualizerItf self,
4769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pStrength)
4770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pStrength)
4772bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pStrength = this->mStrength;
4775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_IsStrengthSupported(SLVirtualizerItf self,
4779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSupported)
4780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSupported)
4782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_TRUE;
4784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVirtualizerItf_ Virtualizer_VirtualizerItf = {
4788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_SetEnabled,
4789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_IsEnabled,
4790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_SetStrength,
4791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_GetRoundedStrength,
4792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_IsStrengthSupported
47932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
47942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
47952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Initial entry points */
47962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
47972045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
47982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
47992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
48002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
48012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEngine)
48022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEngine = NULL;
4804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // default values
4805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean threadSafe = SL_BOOLEAN_TRUE;
480629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE;
4807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != pEngineOptions) {
4808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLuint32 i;
4809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten		const SLEngineOption *option = pEngineOptions;
4810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (i = 0; i < numOptions; ++i, ++option) {
4811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            switch (option->feature) {
4812bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            case SL_ENGINEOPTION_THREADSAFE:
4813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                threadSafe = (SLboolean) option->data;
4814bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                break;
4815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            case SL_ENGINEOPTION_LOSSOFCONTROL:
481629b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten                lossOfControlGlobal = (SLboolean) option->data;
4817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                break;
4818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            default:
4819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
4820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
4821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
4822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
4823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
4824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&Engine_class, numInterfaces,
4825bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
48262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
48272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
482829b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    struct Engine_class *this = (struct Engine_class *)
482929b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        construct(&Engine_class, exposedMask, NULL);
4830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
48312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
483229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0;
483329b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    this->mEngine.mLossOfControlGlobal = lossOfControlGlobal;
4834bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mThreadSafe = threadSafe;
4835bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEngine = &this->mObject.mItf;
48362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
48372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
48382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
48392045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(
48402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pNumSupportedInterfaces)
48412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumSupportedInterfaces)
48432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumSupportedInterfaces = Engine_class.mInterfaceCount;
4845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
48462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
48472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
48482045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index,
48492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLInterfaceID *pInterfaceId)
48502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4851bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]) < index)
4852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pInterfaceId)
48542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pInterfaceId = &SL_IID_array[Engine_interfaces[index].mMPH];
4856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
48572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
48582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
4860bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* OutputMixExt implementation */
4862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Used by SDL and Android but not specific to or dependent on either platform
48642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMixExt_FillBuffer(SLOutputMixExtItf self, void *pBuffer,
4866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 size)
48672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
48682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // Force to be a multiple of a frame, assumes stereo 16-bit PCM
48692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    size &= ~3;
4870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface *thisExt =
4871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct OutputMixExt_interface *) self;
487229b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten    // FIXME Finding one interface from another, but is it exposed?
4873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface *this =
487429b9008a17cae003590a5ff361e98809f02e3025Glenn Kasten        &((struct OutputMix_class *) thisExt->mThis)->mOutputMix;
48752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned activeMask = this->mActiveMask;
48762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = &this->mTracks[0];
48772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned i;
48782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mixBufferHasData = SL_BOOLEAN_FALSE;
48792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME O(32) loop even when few tracks are active.
48802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // To avoid loop, use activeMask to check for active track(s)
48812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // and decide whether we actually need to copy or mix.
48822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    for (i = 0; 0 != activeMask; ++i, ++track, activeMask >>= 1) {
48832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(i < 32);
48842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (!(activeMask & 1))
48852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
48862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is allocated
48872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct Play_interface *play = track->mPlay;
48882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == play)
48892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
48902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is initialized
48912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_PLAYSTATE_PLAYING != play->mState)
48922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
48932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is playing
48942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        void *dstWriter = pBuffer;
48952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned desired = size;
48962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLboolean trackContributedToMix = SL_BOOLEAN_FALSE;
48972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        while (desired > 0) {
48982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            struct BufferQueue_interface *bufferQueue;
48992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            const struct BufferHeader *oldFront, *newFront, *rear;
49002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            unsigned actual = desired;
49012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (track->mAvail < actual)
49022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                actual = track->mAvail;
49032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // force actual to be a frame multiple
49042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (actual > 0) {
49052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME check for either mute or volume 0
49062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // in which case skip the input buffer processing
49072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                assert(NULL != track->mReader);
49082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME && gain == 1.0
49092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (mixBufferHasData) {
4910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    stereo *mixBuffer = (stereo *) dstWriter;
4911bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    const stereo *source = (const stereo *) track->mReader;
49122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    unsigned j;
4913bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    for (j = 0; j < actual; j += sizeof(stereo), ++mixBuffer,
4914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        ++source) {
49152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // apply gain here
49162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->left += source->left;
49172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->right += source->right;
49182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
49192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                } else {
49202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    memcpy(dstWriter, track->mReader, actual);
49212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    trackContributedToMix = SL_BOOLEAN_TRUE;
49222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
49232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                dstWriter = (char *) dstWriter + actual;
49242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                desired -= actual;
49252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mReader = (char *) track->mReader + actual;
49262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mAvail -= actual;
49272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (track->mAvail == 0) {
49282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    bufferQueue = track->mBufferQueue;
49292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (NULL != bufferQueue) {
49302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        oldFront = bufferQueue->mFront;
49312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        rear = bufferQueue->mRear;
49322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(oldFront != rear);
49332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        newFront = oldFront;
4934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        if (++newFront ==
4935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                            &bufferQueue->mArray[bufferQueue->mNumBuffers])
49362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                            newFront = bufferQueue->mArray;
49372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        bufferQueue->mFront = (struct BufferHeader *) newFront;
49382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(0 < bufferQueue->mState.count);
49392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        --bufferQueue->mState.count;
49402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // FIXME here or in Enqueue?
49412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        ++bufferQueue->mState.playIndex;
4942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        // FIXME a good time to do an early warning
49432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // callback depending on buffer count
49442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
49452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
49462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
49472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
49482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // actual == 0
49492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            bufferQueue = track->mBufferQueue;
49502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL != bufferQueue) {
49512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                oldFront = bufferQueue->mFront;
49522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                rear = bufferQueue->mRear;
49532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (oldFront != rear) {
49542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastengot_one:
49552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    assert(0 < bufferQueue->mState.count);
49562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mReader = oldFront->mBuffer;
49572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mAvail = oldFront->mSize;
49582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    continue;
49592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
49602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME should be able to configure when to
49612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // kick off the callback e.g. high/low water-marks etc.
4962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                // need data but none available, attempt a desperate callback
49632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                slBufferQueueCallback callback = bufferQueue->mCallback;
49642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (NULL != callback) {
4965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    (*callback)((SLBufferQueueItf) bufferQueue,
4966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        bufferQueue->mContext);
4967bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    // if lucky, the callback enqueued a buffer
49682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (rear != bufferQueue->mRear)
49692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        goto got_one;
4970bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    // unlucky, queue still empty, the callback failed
49712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
49722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // here on underflow due to no callback, or failed callback
49732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME underflow, send silence (or previous buffer?)
49742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // we did a callback to try to kick start again but failed
49752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // should log this
49762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
4977bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            // no buffer queue or underflow, clear out rest of partial buffer
49782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!mixBufferHasData && trackContributedToMix)
49792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                memset(dstWriter, 0, actual);
49802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
49812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
49822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (trackContributedToMix)
49832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            mixBufferHasData = SL_BOOLEAN_TRUE;
49842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
49852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // No active tracks, so output silence
49862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!mixBufferHasData)
49872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memset(pBuffer, 0, size);
49882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
49892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4990bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf = {
4991bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMixExt_FillBuffer
4992bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_OUTPUTMIXEXT
4995bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
49962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
49972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4998bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME move to separate source file
4999bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
50002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* SDL platform implementation */
50012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
50022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SDLCALL SDL_callback(void *context, Uint8 *stream, int len)
50032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
50042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    assert(len > 0);
5005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMixExt_FillBuffer((SLOutputMixExtItf) context, stream,
5006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (SLuint32) len);
50072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
50082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
50092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenvoid SDL_start(SLObjectItf self)
50102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
5011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //assert(self != NULL);
50122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME make this an operation on Object: GetClass
5013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Object_interface *this = (struct Object_interface *) self;
5014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //assert(&OutputMix_class == this->mClass);
5015bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result;
5016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLOutputMixExtItf OutputMixExt;
5017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    result = (*self)->GetInterface(self, SL_IID_OUTPUTMIXEXT, &OutputMixExt);
5018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
50192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
50202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_AudioSpec fmt;
50212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.freq = 44100;
50222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.format = AUDIO_S16;
50232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.channels = 2;
50242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.samples = 256;
50252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.callback = SDL_callback;
5026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME should be a GetInterface
5027bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // fmt.userdata = &((struct OutputMix_class *) this)->mOutputMixExt;
5028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    fmt.userdata = (void *) OutputMixExt;
50292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
50302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SDL_OpenAudio(&fmt, NULL) < 0) {
50312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
50322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        exit(1);
50332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
50342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_PauseAudio(0);
50352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
50362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SDL
5038d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
5039d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */
5040