sles.cpp revision bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3
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
11bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
12bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "MPH.h"
13bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "MPH_to.h"
142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <sndfile.h>
17bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
18bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <SDL/SDL_audio.h>
21bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SDL
22bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
23bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
24bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#include "OutputMixExt.h"
252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
26d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
27d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Forward declarations */
28d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
29bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenextern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
30bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
31bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef __cplusplus
32bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define this this_
33bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
34d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
35d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private types */
36d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
37bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Hook functions
38bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
39bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef void (*VoidHook)(void *self);
40bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef SLresult (*StatusHook)(void *self);
41bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
42bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Describes how an interface is related to a given class
43bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
44bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_IMPLICIT           0
45bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_EXPLICIT           1
46bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_OPTIONAL           2
47bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC            3
48bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_GAME       INTERFACE_DYNAMIC
49bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_MUSIC      INTERFACE_DYNAMIC
50bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_DYNAMIC_MUSIC_GAME INTERFACE_DYNAMIC
51bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_EXPLICIT_GAME      INTERFACE_EXPLICIT
52bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_GAME               INTERFACE_OPTIONAL
53bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_GAME_MUSIC         INTERFACE_OPTIONAL
54bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_MUSIC_GAME         INTERFACE_OPTIONAL
55bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_OPTIONAL_DYNAMIC   INTERFACE_DYNAMIC
56bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_PHONE_GAME         INTERFACE_OPTIONAL
57bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define INTERFACE_TBD                INTERFACE_IMPLICIT
58bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
59bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Maps an interface ID to its offset within the class that exposes it
60bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
61d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct iid_vtable {
62bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned char mMPH;
63bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned char mInterface;
64bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    /*size_t*/ unsigned short mOffset;
65bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
66bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
67bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Per-class const data shared by all instances of the same class
68bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
69bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct class_ {
70bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // needed by all classes (class class, the superclass of all classes)
71bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *mInterfaces;
72bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mInterfaceCount;
73bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const signed char *mMPH_to_index;
74bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME not yet used
75bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //const char * const mName;
76bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t mSize;
77bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mObjectID;
78bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Non-const here and below should be moved to separate struct,
79bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // as each engine is its own universe.
80bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME not yet used, actually should be per engine, no?
81bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // SLuint32 mInstanceCount;
82bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // append per-class data here
83bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    StatusHook mRealize;
84bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mDestroy;
85d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
86d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
87bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Track describes each input to OutputMixer
88bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME not for Android
89bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
90bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Track {
91bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLDataFormat_PCM *mDfPcm;
92bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *mBufferQueue;
93bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *mPlay; // mixer examines this track if non-NULL
94bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mReader;    // pointer to next frame in BufferHeader.mBuffer
95bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mAvail;        // number of available bytes
96bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
97bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
98bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// BufferHeader describes each element of a BufferQueue, other than the data
99bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct BufferHeader {
101bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mBuffer;
102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mSize;
103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
105bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// stereo is a frame consisting of a pair of 16-bit PCM samples
108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastentypedef struct {
110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short left;
111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short right;
112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} stereo;
113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
116bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_SNDFILE
117bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
118bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct SndFile {
119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // save URI also?
120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLchar *mPathname;
121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SNDFILE *mSNDFILE;
122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // These are used when Enqueue returns SL_RESULT_BUFFER_INSUFFICIENT
123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const void *mRetryBuffer;
124bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mRetrySize;
125bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mIs0; // which buffer to use next
126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME magic numbers
127bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short mBuffer0[512];
128bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    short mBuffer1[512];
129bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
130bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Device table (change this when you port!) */
1342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HEADSET 1
1362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_headset = {
1382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "headset",
1392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_ATTACHED_WIRED,
1402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_USER,
1412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HEADSET,
1422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
1432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
1462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
1472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
1482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
1492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
1502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HANDSFREE 2
1522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_handsfree = {
1542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "handsfree",
1552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_INTEGRATED,
1562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_ENVIRONMENT,
1572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HANDSET,
1582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
1592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
1612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
1622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
1632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
1642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
1652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
1662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
167bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface structures */
1682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
169bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DCommit_interface {
170bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DCommitItf_ *mItf;
171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mDeferred;
173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
174d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
175bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DDoppler_interface {
176bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DDopplerItf_ *mItf;
177bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
178bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    union Cartesian_Spherical1 {
179bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLVec3D mCartesian;
180bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        struct {
181bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mAzimuth;
182bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mElevation;
183bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mSpeed;
184bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        } mSpherical;
185bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } mVelocity;
186bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mDopplerFactor;
187d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
189bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DGrouping_interface {
190bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DGroupingItf_ *mItf;
191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
192bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLObjectItf mGroup;
193bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
194d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
195bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DLocation_interface {
196bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DLocationItf_ *mItf;
197d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    union Cartesian_Spherical2 {
199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLVec3D mCartesian;
200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        struct {
201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mAzimuth;
202bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mElevation;
203bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLmillidegree mDistance;
204bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        } mSpherical;
205bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } mLocation;
206bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mHeading;
207bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mPitch;
208bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree mRoll;
209bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mFront;
210bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mAbove;
211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D mUp;
212d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
213d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
214bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DMacroscopic_interface {
215bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DMacroscopicItf_ *mItf;
216d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
217d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DSource_interface {
220bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SL3DSourceItf_ *mItf;
221d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
222d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
223d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioDecoderCapabilities_interface {
225bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioDecoderCapabilitiesItf_ *mItf;
226d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
227d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
228d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
229bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioEncoder_interface {
230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioEncoderItf_ *mItf;
231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
232bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLAudioEncoderSettings mSettings;
233bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioEncoderCapabilities_interface {
236bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioEncoderCapabilitiesItf_ *mItf;
237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
238bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
240bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct AudioIODeviceCapabilities_interface {
241bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLAudioIODeviceCapabilitiesItf_ *mItf;
242bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
243bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
245bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct BassBoost_interface {
246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLBassBoostItf_ *mItf;
247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnabled;
249bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStrength;
250d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
251d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
252d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct BufferQueue_interface {
253bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLBufferQueueItf_ *mItf;
254d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLBufferQueueState mState;
256d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback mCallback;
257d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
258d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 mNumBuffers;
259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader *mArray;
260bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader *mFront, *mRear;
261bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // saves a malloc in the typical case
262bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define BUFFER_HEADER_TYPICAL 4
263bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferHeader mTypical[BUFFER_HEADER_TYPICAL+1];
264d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
265d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DeviceVolume_interface {
267bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDeviceVolumeItf_ *mItf;
268d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
269bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint32 mVolume;     // FIXME should be per-device
270d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
271d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
272bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DynamicInterfaceManagement_interface {
273bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDynamicInterfaceManagementItf_ *mItf;
274d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
275bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mAddedMask;    // added interfaces, a subset of exposed interfaces
276bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slDynamicInterfaceManagementCallback mCallback;
277bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
278d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
279d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
280bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct DynamicSource_interface {
281bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLDynamicSourceItf_ *mItf;
282d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
285bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EffectSend_interface {
286bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEffectSendItf_ *mItf;
287d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
288d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
289d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
290bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Engine_interface {
291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEngineItf_ *mItf;
2922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
293bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Per-class non-const data such as vector of created objects
2942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
295d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EngineCapabilities_interface {
297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEngineCapabilitiesItf_ *mItf;
298d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
2992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
301bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct EnvironmentalReverb_interface {
302bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEnvironmentalReverbItf_ *mItf;
3032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
306bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Equalizer_interface {
307bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLEqualizerItf_ *mItf;
3082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
311bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct LEDArray_interface {
312bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLLEDArrayItf_ *mItf;
3132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
316bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MetaDataExtraction_interface {
317bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMetaDataExractionItf_ *mItf;
3182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
321bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MetaDataTraversal_interface {
322bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMetaDataTraversalItf_ *mItf;
3232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDIMessage_interface {
327bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDIMessageItf_ *mItf;
3282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
331bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDIMuteSolo_interface {
332bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDIMuteSoloItf_ *mItf;
3332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
336bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDITempo_interface {
337bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDITempoItf_ *mItf;
3382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
341bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MIDITime_interface {
342bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMIDITimeItf_ *mItf;
3432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
346bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct MuteSolo_interface {
347bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLMuteSoloItf_ *mItf;
3482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
351bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Object_interface {
352bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLObjectItf_ *mItf;
353bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // probably not needed for an Object, as it is always first
3542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *mClass;
356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    volatile SLuint32 mState;
357bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slObjectCallback mCallback;
358bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
359bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mExposedMask;  // exposed interfaces
360bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint32 mPriority;
361bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mPreemptable;
362bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME a thread lock would go here
363bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME also an object ID for RPC
364bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME and a human-readable name for debugging
3652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
367bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMix_interface {
368bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLOutputMixItf_ *mItf;
3692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
370bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mActiveMask;   // 1 bit per active track
371bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Track mTracks[32];
3722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
374bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
375bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMixExt_interface {
376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLOutputMixExtItf_ *mItf;
3772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
3802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
381bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Pitch_interface {
382bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPitchItf_ *mItf;
3832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Play_interface {
387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPlayItf_ *mItf;
3882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
389bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    volatile SLuint32 mState;
390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mDuration;
391bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPosition;
392bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // unsigned mPositionSamples;  // position in sample units
393bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slPlayCallback mCallback;
394bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
395bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mEventFlags;
396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mMarkerPosition;
397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPositionUpdatePeriod;
3982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
400bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PlaybackRate_interface {
401bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPlaybackRateItf_ *mItf;
4022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
4032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
405bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PrefetchStatus_interface {
406bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPrefetchStatusItf_ *mItf;
4072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
4082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct PresetReverb_interface {
411bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLPresetReverbItf_ *mItf;
4122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
413bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 mPreset;
4142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
416bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct RatePitch_interface {
417bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLRatePitchItf_ *mItf;
4182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
4192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Record_interface {
422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLRecordItf_ *mItf;
4232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
424d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
425d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
426bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Seek_interface {
427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLSeekItf_ *mItf;
428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mPos;
430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mLoopEnabled;
431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mStartPos;
432bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mEndPos;
433bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
434d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
435bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct ThreadSync_interface {
436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLThreadSyncItf_ *mItf;
437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
438d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
439d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
440bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Vibra_interface {
441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVibraItf_ *mItf;
442bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
443d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
444d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Virtualizer_interface {
446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVirtualizerItf_ *mItf;
447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnabled;
449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStrength;
4502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
452bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Visualization_interface {
453bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVisualizationItf_ *mItf;
454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slVisualizationCallback mCallback;
456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *mContext;
457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz mRate;
458bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
459bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Volume_interface {
461bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct SLVolumeItf_ *mItf;
462bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
463bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel mLevel;
464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mMute;
465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mEnableStereoPosition;
466bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille mStereoPosition;
467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
468bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Class structures */
470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
471bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct _3DGroup_class {
4722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
4732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
4782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
480d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct AudioPlayer_class {
481d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
482d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
483d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface mPlay;
484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface m3DGrouping;
486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
488d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface mBufferQueue;
4892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct EffectSend_interface mEffectSend;
4902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MuteSolo_interface mMuteSolo;
4912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
4922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
4932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct PrefetchStatus_interface mPrefetchStatus;
4942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct RatePitch_interface mRatePitch;
4952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
4962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface mVolume;
4972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // optional interfaces
498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
500bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Pitch_interface mPitch;
504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PlaybackRate_interface mPlaybackRate;
506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
5082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // rest of fields are not related to the interfaces
5092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
510bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct SndFile mSndFile;
511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME union per kind of AudioPlayer: MediaPlayer, AudioTrack, etc.
5132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioRecorder_class {
516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Record_interface mRecord;
5202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioEncoder_interface mAudioEncoder;
521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
526d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
527d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
528d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct Engine_class {
530bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated implicit interfaces
531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Engine_interface mEngine;
534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EngineCapabilities_interface mEngineCapabilities;
535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct ThreadSync_interface mThreadSync;
536bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated explicit interfaces
537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioIODeviceCapabilities_interface mAudioIODeviceCapabilities;
538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioDecoderCapabilities_interface mAudioDecoderCapabilities;
539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoderCapabilities_interface mAudioEncoderCapabilities;
540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface m3DCommit;
541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface mDeviceVolume;
543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // additional fields not associated with interfaces
544bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mThreadSafe;
545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mLossOfControl;
546bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct LEDDevice_class {
549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
551bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct LEDArray_interface mLED;
553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //
554bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mDeviceID;
555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
5572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Listener_class {
558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
5622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DLocation_interface m3DLocation;
5632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MetadataExtractor_class {
566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicSource_interface mDynamicSource;
5702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
5712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
5722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MidiPlayer_class {
575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
5762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
5772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
5782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface mPlay;
579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface m3DGrouping;
581bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface m3DLocation;
582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DSource_interface m3DSource;
583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface mBufferQueue;
584bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EffectSend_interface mEffectSend;
585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MuteSolo_interface mMuteSolo;
586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDIMessage_interface mMIDIMessage;
589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDITime_interface mMIDITime;
590bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDITempo_interface mMIDITempo;
591bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MIDIMuteSolo_interface mMIDIMuteSolo;
592bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PrefetchStatus_interface mPrefetchStatus;
5932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface mVolume;
595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DMacroscopic_interface m3DMacroscopic;
597bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
598bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicSource_interface mDynamicSource;
599bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
601bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Pitch_interface mPitch;
602bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
603bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PlaybackRate_interface mPlaybackRate;
604bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
605bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
6062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
6072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
608bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct OutputMix_class {
609bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface mOutputMix;
613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface mOutputMixExt;
615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Equalizer_interface mEqualizer;
618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface mPresetReverb;
619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface mVirtualizer;
620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface mVolume;
621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // optional interfaces
622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface mBassBoost;
623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface mVisualization;
624bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
625d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstruct VibraDevice_class {
627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // mandated interfaces
628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface mObject;
629bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Vibra_interface mVibra;
631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //
632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mDeviceID;
633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Private functions */
636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
637bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Map SLInterfaceID to its minimal perfect hash (MPH), or -1 if unknown
638bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
639bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic int IID_to_MPH(const SLInterfaceID iid)
640d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid)
642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return iid - &SL_IID_array[0];
643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != iid) {
644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME Replace this linear search by a good MPH algorithm
645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        const struct SLInterfaceID_ *srch = &SL_IID_array[0];
646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        unsigned MPH;
647bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (MPH = 0; MPH < MPH_MAX; ++MPH, ++srch)
648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (!memcmp(iid, srch, sizeof(struct SLInterfaceID_)))
649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return MPH;
650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return -1;
652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult checkInterfaces(const struct class_ *class__,
655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
656bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLboolean *pInterfaceRequired, unsigned *pExposedMask)
657bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
658bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(NULL != class__ && NULL != pExposedMask);
659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask = 0;
660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *interfaces = class__->mInterfaces;
661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 interfaceCount = class__->mInterfaceCount;
662bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 i;
663bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME This section could be pre-computed per class
664bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    for (i = 0; i < interfaceCount; ++i) {
665bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        switch (interfaces[i].mInterface) {
666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        case INTERFACE_IMPLICIT:
667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            exposedMask |= 1 << i;
668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            break;
669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        default:
670bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            break;
671bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
673d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (0 < numInterfaces) {
674d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == pInterfaceIds || NULL == pInterfaceRequired)
675d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
676d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        for (i = 0; i < numInterfaces; ++i) {
677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLInterfaceID iid = pInterfaceIds[i];
678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (NULL == iid)
679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
680bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            int mph = IID_to_MPH(iid);
681bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (mph < 0) {
682bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                if (pInterfaceRequired[i])
683bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    return SL_RESULT_FEATURE_UNSUPPORTED;
684bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                continue;
685bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
686bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            int interfaceIndex = class__->mMPH_to_index[mph];
687bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (interfaceIndex < 0) {
688bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                if (pInterfaceRequired[i])
689bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    return SL_RESULT_FEATURE_UNSUPPORTED;
690bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                continue;
691d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
692bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (exposedMask & (1 << interfaceIndex))
693bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#if 0 // FIXME this seems a bit strong? what is correct logic?
694bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// we are requesting a duplicate explicit interface,
695bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// or we are requesting one which is already implicit ?
696bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
697bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
698bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                continue;
699bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
700bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            exposedMask |= (1 << interfaceIndex);
701d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
702d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pExposedMask = exposedMask;
704d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
705d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
706d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
707bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface initialization hooks */
708d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DCommit_init(void *self)
710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
711bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SL3DCommitItf_ _3DCommit_3DCommitItf;
712bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface *this = (struct _3DCommit_interface *) self;
713bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &_3DCommit_3DCommitItf;
714bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDeferred = SL_BOOLEAN_FALSE;
716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
718d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
719bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DDoppler_init(void *self)
720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DDoppler_interface *this =
722bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DDoppler_interface *) self;
723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
724d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DGrouping_init(void *self)
726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DGrouping_interface *this =
728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DGrouping_interface *) self;
729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
730d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DLocation_init(void *self)
732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DLocation_interface *this =
734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DLocation_interface *) self;
735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
736d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DMacroscopic_init(void *self)
738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
739bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DMacroscopic_interface *this =
740bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DMacroscopic_interface *) self;
741bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
742d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void _3DSource_init(void *self)
744bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct _3DSource_interface *this =
746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct _3DSource_interface *) self;
747bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
748d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioDecoderCapabilities_init(void *self)
750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLAudioDecoderCapabilitiesItf_
752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        AudioDecoderCapabilities_AudioDecoderCapabilitiesItf;
753bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioDecoderCapabilities_interface *this =
754bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioDecoderCapabilities_interface *) self;
755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioDecoderCapabilities_AudioDecoderCapabilitiesItf;
756bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
7572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
758bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioEncoderCapabilities_init(void *self)
759bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
760bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLAudioEncoderCapabilitiesItf_
761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        AudioEncoderCapabilities_AudioEncoderCapabilitiesItf;
762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoderCapabilities_interface *this =
763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoderCapabilities_interface *) self;
764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioEncoderCapabilities_AudioEncoderCapabilitiesItf;
765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
7662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
767bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioEncoder_init(void *self)
768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct AudioEncoder_interface *this =
770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct AudioEncoder_interface *) self;
771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
7722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioIODeviceCapabilities_init(void *self)
774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLAudioIODeviceCapabilitiesItf_
776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioIODeviceCapabilities_interface *this =
778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioIODeviceCapabilities_interface *) self;
779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
7812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void BassBoost_init(void *self)
783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct BassBoost_interface *this =
785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct BassBoost_interface *) self;
786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
7872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void BufferQueue_init(void *self)
789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf;
791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &BufferQueue_BufferQueueItf;
793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
794bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState.count = 0;
795bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState.playIndex = 0;
796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mNumBuffers = 0;
799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mArray = NULL;
800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = NULL;
801bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRear = NULL;
802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
8042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DeviceVolume_init(void *self)
806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf;
808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &DeviceVolume_DeviceVolumeItf;
811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
812d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DynamicInterfaceManagement_init(void *self)
814d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLDynamicInterfaceManagementItf_
816bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        DynamicInterfaceManagement_DynamicInterfaceManagementItf;
817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf =
820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAddedMask = 0;
823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
825bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
826d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
827d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
828bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void DynamicSource_init(void *self)
829d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct DynamicSource_interface *this =
831bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct DynamicSource_interface *) self;
832d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
833d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
834bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EffectSend_init(void *self)
835d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
836bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct EffectSend_interface *this =
837bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct EffectSend_interface *) self;
838d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
839d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Engine_init(void *self)
841d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLEngineItf_ Engine_EngineItf;
843bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Engine_interface *this = (struct Engine_interface *) self;
844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Engine_EngineItf;
845d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
846d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EngineCapabilities_init(void *self)
848d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
849bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLEngineCapabilitiesItf_
850bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        EngineCapabilities_EngineCapabilitiesItf;
851bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct EngineCapabilities_interface *this =
852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct EngineCapabilities_interface *) self;
853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &EngineCapabilities_EngineCapabilitiesItf;
854d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
855d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void EnvironmentalReverb_init(void *self)
857d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct EnvironmentalReverb_interface *this =
859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        //(struct EnvironmentalReverb_interface *) self;
860d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
861d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Equalizer_init(void *self)
863d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Equalizer_interface *this =
865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Equalizer_interface *) self;
866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
867bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
868bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void LEDArray_init(void *self)
869bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLLEDArrayItf_ LEDArray_LEDArrayItf;
871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct LEDArray_interface *this = (struct LEDArray_interface *) self;
872bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &LEDArray_LEDArrayItf;
873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
874bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
875bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MetaDataExtraction_init(void *self)
876bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
877bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MetaDataExtraction_interface *this =
878bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MetaDataExtraction_interface *) self;
879bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
880bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
881bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MetaDataTraversal_init(void *self)
882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
883bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MetaDataTraversal_interface *this =
884bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MetaDataTraversal_interface *) self;
885bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
886bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
887bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDIMessage_init(void *self)
888bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
889bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDIMessage_interface *this =
890bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDIMessage_interface *) self;
891bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
892bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDIMuteSolo_init(void *self)
894bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
895bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDIMuteSolo_interface *this =
896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDIMuteSolo_interface *) self;
897bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
898bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
899bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDITempo_init(void *self)
900bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDITempo_interface *this =
902bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDITempo_interface *) self;
903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
904bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MIDITime_init(void *self)
906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MIDITime_interface *this =
908bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MIDITime_interface *) self;
909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
911bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void MuteSolo_init(void *self)
912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
913bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct MuteSolo_interface *this =
914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct MuteSolo_interface *) self;
915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
917bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PrefetchStatus_init(void *self)
918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
919bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PrefetchStatus_interface *this =
920bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct PrefetchStatus_interface *) self;
921bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
922bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
923bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_init(void *self)
924bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
925bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLObjectItf_ Object_ObjectItf;
926d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
927bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Object_ObjectItf;
928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_UNREALIZED;
929bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
930bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
931bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
932bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPriority = 0;
933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreemptable = SL_BOOLEAN_FALSE;
934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
935d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
936d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
937bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMix_init(void *self)
938d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
939bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLOutputMixItf_ OutputMix_OutputMixItf;
940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface *this = (struct OutputMix_interface *) self;
941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &OutputMix_OutputMixItf;
942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
943bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mActiveMask = 0;
944bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Track *track = &this->mTracks[0];
945bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME O(n)
946bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME magic number
947bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned i;
948bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    for (i = 0; i < 32; ++i, ++track)
949bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        track->mPlay = NULL;
950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
952d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMixExt_init(void *self)
955d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf;
957bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface *this =
958bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct OutputMixExt_interface *) self;
959bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &OutputMixExt_OutputMixExtItf;
960d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
961bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_OUTPUTMIXEXT
962d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Pitch_init(void *self)
964d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Pitch_interface *this =
966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Pitch_interface *) self;
967d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
968d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
969bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Play_init(void *self)
970bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
971bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLPlayItf_ Play_PlayItf;
972bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Play_PlayItf;
974bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mState = SL_PLAYSTATE_STOPPED;
975bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDuration = SL_TIME_UNKNOWN;
976bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
977bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPosition = (SLmillisecond) 0;
978bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // this->mPlay.mPositionSamples = 0;
979bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
980bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
981bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEventFlags = 0;
982bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = 0;
983bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPositionUpdatePeriod = 0;
984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
986bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
987bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PlaybackRate_init(void *self)
988bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
989bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PlaybackRate_interface *this =
990bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct PlaybackRate_interface *) self;
991bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
992bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void PresetReverb_init(void *self)
994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
995bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct PresetReverb_interface *this =
996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        //(struct PresetReverb_interface *) self;
997bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
998bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
999bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void RatePitch_init(void *self)
1000bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1001bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct RatePitch_interface *this =
1002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct RatePitch_interface *) self;
1003bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1004bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Record_init(void *self)
1006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1007bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Record_interface *this = (struct Record_interface *) self;
1008bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1009bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1010bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Seek_init(void *self)
1011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1012bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLSeekItf_ Seek_SeekItf;
1013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
1014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Seek_SeekItf;
1015bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPos = (SLmillisecond) -1;
1016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStartPos = (SLmillisecond) -1;
1017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEndPos = (SLmillisecond) -1;
1018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1019bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLoopEnabled = SL_BOOLEAN_FALSE;
1020bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1021bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1022bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1023bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void ThreadSync_init(void *self)
1024bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1025bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf;
1026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct ThreadSync_interface *this =
1027bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct ThreadSync_interface *) self;
1028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &ThreadSync_ThreadSyncItf;
1029bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1030bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1031bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Virtualizer_init(void *self)
1032bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1033bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Virtualizer_interface *this =
1034bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // (struct Virtualizer_interface *) self;
1035bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1036bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Vibra_init(void *self)
1038bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1039bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLVibraItf_ Vibra_VibraItf;
1040bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Vibra_interface *this = (struct Vibra_interface *) self;
1041bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Vibra_VibraItf;
1042bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1043bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Visualization_init(void *self)
1045bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1046bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLVisualizationItf_ Visualization_VisualizationItf;
1047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface *this =
1048bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Visualization_interface *) self;
1049bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Visualization_VisualizationItf;
1050bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1051bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = NULL;
1052bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = NULL;
1053bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRate = 0;
1054bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1055bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1056bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1057bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Volume_init(void *self)
1058bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1059bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    extern const struct SLVolumeItf_ Volume_VolumeItf;
1060bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
1061bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mItf = &Volume_VolumeItf;
1062bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1063bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLevel = 0; // FIXME correct ?
1064bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMute = SL_BOOLEAN_FALSE;
1065bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnableStereoPosition = SL_BOOLEAN_FALSE;
1066bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStereoPosition = 0;
1067bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1069bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1070bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct MPH_init {
1071bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // unsigned char mMPH;
1072bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mInit;
1073bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook mDeinit;
1074bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten} MPH_init_table[MPH_MAX] = {
1075bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DCOMMIT, */ _3DCommit_init, NULL },
1076bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DDOPPLER, */ _3DDoppler_init, NULL },
1077bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DGROUPING, */ _3DGrouping_init, NULL },
1078bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DLOCATION, */ _3DLocation_init, NULL },
1079bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DMACROSCOPIC, */ _3DMacroscopic_init, NULL },
1080bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_3DSOURCE, */ _3DSource_init, NULL },
1081bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIODECODERCAPABILITIES, */ AudioDecoderCapabilities_init, NULL },
1082bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOENCODER, */ AudioEncoder_init, NULL },
1083bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOENCODERCAPABILITIES, */ AudioEncoderCapabilities_init, NULL },
1084bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_AUDIOIODEVICECAPABILITIES, */ AudioIODeviceCapabilities_init,
1085bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL },
1086bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_BASSBOOST, */ BassBoost_init, NULL },
1087bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_BUFFERQUEUE, */ BufferQueue_init, NULL },
1088bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DEVICEVOLUME, */ DeviceVolume_init, NULL },
1089bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ DynamicInterfaceManagement_init,
1090bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL },
1091bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_DYNAMICSOURCE, */ DynamicSource_init, NULL },
1092bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_EFFECTSEND, */ EffectSend_init, NULL },
1093bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENGINE, */ Engine_init, NULL },
1094bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENGINECAPABILITIES, */ EngineCapabilities_init, NULL },
1095bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_ENVIRONMENTALREVERB, */ EnvironmentalReverb_init, NULL },
1096bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_EQUALIZER, */ Equalizer_init, NULL },
1097bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_LED, */ LEDArray_init, NULL },
1098bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_METADATAEXTRACTION, */ MetaDataExtraction_init, NULL },
1099bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_METADATATRAVERSAL, */ MetaDataTraversal_init, NULL },
1100bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDIMESSAGE, */ MIDIMessage_init, NULL },
1101bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDITIME, */ MIDITime_init, NULL },
1102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDITEMPO, */ MIDITempo_init, NULL },
1103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MIDIMUTESOLO, */ MIDIMuteSolo_init, NULL },
1104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_MUTESOLO, */ MuteSolo_init, NULL },
1105bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_NULL, */ NULL, NULL },
1106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OBJECT, */ Object_init, NULL },
1107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OUTPUTMIX, */ OutputMix_init, NULL },
1108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PITCH, */ Pitch_init, NULL },
1109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PLAY, */ Play_init, NULL },
1110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PLAYBACKRATE, */ PlaybackRate_init, NULL },
1111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PREFETCHSTATUS, */ PrefetchStatus_init, NULL },
1112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_PRESETREVERB, */ PresetReverb_init, NULL },
1113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_RATEPITCH, */ RatePitch_init, NULL },
1114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_RECORD, */ Record_init, NULL },
1115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_SEEK, */ Seek_init, NULL },
1116bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_THREADSYNC, */ ThreadSync_init, NULL },
1117bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VIBRA, */ Vibra_init, NULL },
1118bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VIRTUALIZER, */ Virtualizer_init, NULL },
1119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VISUALIZATION, */ Visualization_init, NULL },
1120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_VOLUME, */ Volume_init, NULL },
1121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    { /* MPH_OUTPUTMIXEXT, */
1122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1123bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        OutputMixExt_init, NULL
1124bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1125bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        NULL, NULL
1126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1127bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
1128bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1129bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1130bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Classes vs. interfaces */
1131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// 3DGroup class
1133bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1134bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable _3DGroup_interfaces[] = {
1135bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1136bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, mObject)},
1137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, mDynamicInterfaceManagement)},
1139bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_IMPLICIT,
1140bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DLocation)},
1141bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1142bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1143bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1144bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DSource)},
1145bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1146bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DMacroscopic)},
1147bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1148bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1149bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ _3DGroup_class = {
1150bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGroup_interfaces,
1151bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(_3DGroup_interfaces)/sizeof(_3DGroup_interfaces[0]),
1152bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_3DGroup,
1153bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"3DGroup",
1154bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct _3DGroup_class),
1155bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_3DGROUP,
1156bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1157bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1158d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1159d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1160bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// AudioPlayer class
1161bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1162bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* AudioPlayer private functions */
11632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
11642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
11652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
11662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread
11672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext)
11682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
11692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct SndFile *this = (struct SndFile *) pContext;
11702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result;
11712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) {
1172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        result = (*caller)->Enqueue(caller, this->mRetryBuffer,
1173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            this->mRetrySize);
11742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result)
11752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;     // what, again?
11762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
11772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetryBuffer = NULL;
11782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetrySize = 0;
11792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return;
11802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
11812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1;
11822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mIs0 ^= SL_BOOLEAN_TRUE;
11832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sf_count_t count;
11842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME magic number
11852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512);
11862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (0 < count) {
11872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 size = count * sizeof(short);
11882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME if we had an internal API, could call this directly
11892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        result = (*caller)->Enqueue(caller, pBuffer, size);
11902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result) {
11912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetryBuffer = pBuffer;
11922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetrySize = size;
11932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;
11942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
11952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
11962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
11972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
11982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
11992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLboolean SndFile_IsSupported(const SF_INFO *sfinfo)
12002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
12012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_TYPEMASK) {
12022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_WAV:
12032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_SUBMASK) {
12082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_PCM_16:
12092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->samplerate) {
12142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 44100:
12152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->channels) {
12202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 2:
12212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
12222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
12232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
12242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
12252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_BOOLEAN_TRUE;
12262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
12272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
12292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#if 0
1231bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLObjectItf_ AudioPlayer_ObjectItf = {
1232bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Realize,
1233bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Resume,
1234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_GetState,
1235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_GetInterface,
1236bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_RegisterCallback,
1237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_AbortAsyncOperation,
1238bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Destroy,
1239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_SetPriority,
1240bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_GetPriority,
1241bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_SetLossOfControlInterfaces,
1242bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1243bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1245bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult AudioPlayer_Realize(void *self)
1246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
1248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
1249bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // for Android here is where we do setDataSource etc. for MediaPlayer
1250bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_SNDFILE
12512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mPathname) {
12522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SF_INFO sfinfo;
12532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sfinfo.format = 0;
12542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = sf_open(
12552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (const char *) this->mSndFile.mPathname, SFM_READ, &sfinfo);
12562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == this->mSndFile.mSNDFILE) {
12572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_NOT_FOUND;
12582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else if (!SndFile_IsSupported(&sfinfo)) {
12592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            sf_close(this->mSndFile.mSNDFILE);
12602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mSndFile.mSNDFILE = NULL;
12612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_UNSUPPORTED;
12622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else {
1263bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SLBufferQueueItf bufferQueue = &this->mBufferQueue.mItf;
12642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME should use a private internal API, and disallow
12652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // application to have access to our buffer queue
12662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME if we had an internal API, could call this directly
1267bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            result = (*bufferQueue)->RegisterCallback(bufferQueue,
1268bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                SndFile_Callback, &this->mSndFile);
12692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
12702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
1271bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
12722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return result;
12732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
12742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1275bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void AudioPlayer_Destroy(void *self)
12762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
12772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
12782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME stop the player in a way that app can't restart it
1279bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Free the buffer queue, if it was larger than typical
1280bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != this->mBufferQueue.mArray &&
1281bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray != this->mBufferQueue.mTypical) {
12822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        free(this->mBufferQueue.mArray);
1283bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = NULL;
1284bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
12852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
12862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mSNDFILE) {
12872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sf_close(this->mSndFile.mSNDFILE);
12882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = NULL;
12892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
1290bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
1291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1292bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1293bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable AudioPlayer_interfaces[] = {
1294bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1295bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mObject)},
1296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mDynamicInterfaceManagement)},
1298bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAY, INTERFACE_IMPLICIT,
1299bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPlay)},
1300bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1301bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DDoppler)},
1302bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DGROUPING, INTERFACE_GAME,
1303bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DGrouping)},
1304bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_GAME,
1305bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DLocation)},
1306bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1307bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DSource)},
1308bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Currently we create an internal buffer queue for playing files
1309bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BUFFERQUEUE, /* INTERFACE_GAME */ INTERFACE_IMPLICIT,
1310bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mBufferQueue)},
1311bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EFFECTSEND, INTERFACE_MUSIC_GAME,
1312bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEffectSend)},
1313bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MUTESOLO, INTERFACE_GAME,
1314bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMuteSolo)},
1315bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_MUSIC_GAME,
1316bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMetaDataExtraction)},
1317bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_MUSIC_GAME,
1318bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mMetaDataTraversal)},
1319bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PREFETCHSTATUS, INTERFACE_TBD,
1320bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPrefetchStatus)},
1321bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_RATEPITCH, INTERFACE_DYNAMIC_GAME,
1322bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mRatePitch)},
1323bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_SEEK, INTERFACE_TBD,
1324bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mSeek)},
1325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_TBD,
1326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVolume)},
1327bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1328bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, m3DMacroscopic)},
1329bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1330bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mBassBoost)},
1331bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1332bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mDynamicSource)},
1333bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL,
1334bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEnvironmentalReverb)},
1335bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1336bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mEqualizer)},
1337bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PITCH, INTERFACE_OPTIONAL,
1338bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPitch)},
1339bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_OPTIONAL,
1340bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPresetReverb)},
1341bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL,
1342bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mPlaybackRate)},
1343bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_OPTIONAL,
1344bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVirtualizer)},
1345bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1346bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioPlayer_class, mVisualization)}
1347bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1348bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1349bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ AudioPlayer_class = {
1350bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_interfaces,
1351bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(AudioPlayer_interfaces)/sizeof(AudioPlayer_interfaces[0]),
1352bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_AudioPlayer,
1353bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"AudioPlayer",
1354bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct AudioPlayer_class),
1355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_AUDIOPLAYER,
1356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_Realize,
1357bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioPlayer_Destroy
1358bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1359bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1360bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// AudioRecorder class
1361bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1362bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable AudioRecorder_interfaces[] = {
1363bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1364bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mObject)},
1365bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1366bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mDynamicInterfaceManagement)},
1367bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_RECORD, INTERFACE_IMPLICIT,
1368bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mRecord)},
1369bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOENCODER, INTERFACE_TBD,
1370bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mAudioEncoder)},
1371bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1372bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mBassBoost)},
1373bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1374bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mDynamicSource)},
1375bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mEqualizer)},
1377bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1378bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mVisualization)},
1379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_OPTIONAL,
1380bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct AudioRecorder_class, mVolume)}
1381bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1382bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1383bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ AudioRecorder_class = {
1384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioRecorder_interfaces,
1385bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(AudioRecorder_interfaces)/sizeof(AudioRecorder_interfaces[0]),
1386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_AudioRecorder,
1387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"AudioRecorder",
1388bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct AudioRecorder_class),
1389bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_AUDIORECORDER,
1390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1391bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1392bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1393bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1394bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Engine class
1395bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable Engine_interfaces[] = {
1397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1398bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mObject)},
1399bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1400bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mDynamicInterfaceManagement)},
1401bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENGINE, INTERFACE_IMPLICIT,
1402bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mEngine)},
1403bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENGINECAPABILITIES, INTERFACE_IMPLICIT,
1404bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mEngineCapabilities)},
1405bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_THREADSYNC, INTERFACE_IMPLICIT,
1406bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mThreadSync)},
1407bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOIODEVICECAPABILITIES, INTERFACE_IMPLICIT,
1408bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioIODeviceCapabilities)},
1409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIODECODERCAPABILITIES, INTERFACE_EXPLICIT,
1410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioDecoderCapabilities)},
1411bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_AUDIOENCODERCAPABILITIES, INTERFACE_EXPLICIT,
1412bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mAudioEncoderCapabilities)},
1413bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DCOMMIT, INTERFACE_EXPLICIT_GAME,
1414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, m3DCommit)},
1415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DEVICEVOLUME, INTERFACE_OPTIONAL,
1416bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Engine_class, mDeviceVolume)}
1417bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1418bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1419bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ Engine_class = {
1420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Engine_interfaces,
1421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]),
1422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Engine,
1423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"Engine",
1424bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct Engine_class),
1425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_ENGINE,
1426bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// LEDDevice class
1431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1432bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable LEDDevice_interfaces[] = {
1433bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1434bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mObject)},
1435bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mDynamicInterfaceManagement)},
1437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_LED, INTERFACE_IMPLICIT,
1438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct LEDDevice_class, mLED)}
1439bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1440bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ LEDDevice_class = {
1442bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDDevice_interfaces,
1443bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(LEDDevice_interfaces)/sizeof(LEDDevice_interfaces[0]),
1444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_LEDDevice,
1445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"LEDDevice",
1446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct LEDDevice_class),
1447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_LEDDEVICE,
1448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1451bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1452bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Listener class
1453bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable Listener_interfaces[] = {
1455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Listener_class, mObject)},
1457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1458bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct Listener_class, mDynamicInterfaceManagement)},
1459bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1461bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_EXPLICIT_GAME,
1462bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DLocation)}
1463bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ Listener_class = {
1466bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Listener_interfaces,
1467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(Listener_interfaces)/sizeof(Listener_interfaces[0]),
1468bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Listener,
1469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"Listener",
1470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct Listener_class),
1471bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_LISTENER,
1472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// MetadataExtractor class
1477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1478bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable MetadataExtractor_interfaces[] = {
1479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mObject)},
1481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mDynamicInterfaceManagement)},
1483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_IMPLICIT,
1484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mDynamicSource)},
1485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_IMPLICIT,
1486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mMetaDataExtraction)},
1487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_IMPLICIT,
1488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MetadataExtractor_class, mMetaDataTraversal)}
1489bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ MetadataExtractor_class = {
1492bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtractor_interfaces,
1493bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(MetadataExtractor_interfaces) /
1494bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        sizeof(MetadataExtractor_interfaces[0]),
1495bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_MetadataExtractor,
1496bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"MetadataExtractor",
1497bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct MetadataExtractor_class),
1498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_METADATAEXTRACTOR,
1499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1500bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// MidiPlayer class
1504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable MidiPlayer_interfaces[] = {
1506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mObject)},
1508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1509bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mDynamicInterfaceManagement)},
1510bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAY, INTERFACE_IMPLICIT,
1511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPlay)},
1512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DDOPPLER, INTERFACE_DYNAMIC_GAME,
1513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct _3DGroup_class, m3DDoppler)},
1514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DGROUPING, INTERFACE_GAME,
1515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DGrouping)},
1516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DLOCATION, INTERFACE_GAME,
1517bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DLocation)},
1518bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DSOURCE, INTERFACE_GAME,
1519bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DSource)},
1520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BUFFERQUEUE, INTERFACE_GAME,
1521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mBufferQueue)},
1522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EFFECTSEND, INTERFACE_GAME,
1523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEffectSend)},
1524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MUTESOLO, INTERFACE_GAME,
1525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMuteSolo)},
1526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATAEXTRACTION, INTERFACE_GAME,
1527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMetaDataExtraction)},
1528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_METADATATRAVERSAL, INTERFACE_GAME,
1529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMetaDataTraversal)},
1530bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDIMESSAGE, INTERFACE_PHONE_GAME,
1531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDIMessage)},
1532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDITIME, INTERFACE_PHONE_GAME,
1533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDITime)},
1534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDITEMPO, INTERFACE_PHONE_GAME,
1535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDITempo)},
1536bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_MIDIMUTESOLO, INTERFACE_GAME,
1537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mMIDIMuteSolo)},
1538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PREFETCHSTATUS, INTERFACE_PHONE_GAME,
1539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPrefetchStatus)},
1540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_SEEK, INTERFACE_PHONE_GAME,
1541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mSeek)},
1542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_PHONE_GAME,
1543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVolume)},
1544bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_3DMACROSCOPIC, INTERFACE_OPTIONAL,
1545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, m3DMacroscopic)},
1546bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL,
1547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mBassBoost)},
1548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICSOURCE, INTERFACE_OPTIONAL,
1549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mDynamicSource)},
1550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_OPTIONAL,
1551bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEnvironmentalReverb)},
1552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_OPTIONAL,
1553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mEqualizer)},
1554bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PITCH, INTERFACE_OPTIONAL,
1555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPitch)},
1556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_OPTIONAL,
1557bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPresetReverb)},
1558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PLAYBACKRATE, INTERFACE_OPTIONAL,
1559bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mPlaybackRate)},
1560bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_OPTIONAL,
1561bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVirtualizer)},
1562bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct MidiPlayer_class, mVisualization)}
1564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ MidiPlayer_class = {
1567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MidiPlayer_interfaces,
1568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(MidiPlayer_interfaces)/sizeof(MidiPlayer_interfaces[0]),
1569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_MidiPlayer,
1570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"MidiPlayer",
1571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct MidiPlayer_class),
1572bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_MIDIPLAYER,
1573bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1574bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// OutputMix class
1578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable OutputMix_interfaces[] = {
1580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_IMPLICIT,
1581bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mObject)},
1582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
1583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mDynamicInterfaceManagement)},
1584bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIX, INTERFACE_IMPLICIT,
1585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mOutputMix)},
1586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
1587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIXEXT, INTERFACE_IMPLICIT,
1588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mOutputMixExt)},
1589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1590bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OUTPUTMIXEXT, INTERFACE_TBD /*NOT AVAIL*/, 0},
1591bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1592bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_ENVIRONMENTALREVERB, INTERFACE_DYNAMIC_GAME,
1593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mEnvironmentalReverb)},
1594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_EQUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME,
1595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mEqualizer)},
1596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_PRESETREVERB, INTERFACE_DYNAMIC_MUSIC,
1597bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mPresetReverb)},
1598bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIRTUALIZER, INTERFACE_DYNAMIC_MUSIC_GAME,
1599bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVirtualizer)},
1600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VOLUME, INTERFACE_GAME_MUSIC,
1601bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVolume)},
1602bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_BASSBOOST, INTERFACE_OPTIONAL_DYNAMIC,
1603bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mBassBoost)},
1604bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VISUALIZATION, INTERFACE_OPTIONAL,
1605bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct OutputMix_class, mVisualization)}
1606bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1607bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1608bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ OutputMix_class = {
1609bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMix_interfaces,
1610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(OutputMix_interfaces)/sizeof(OutputMix_interfaces[0]),
1611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_OutputMix,
1612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"OutputMix",
1613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct OutputMix_class),
1614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_OUTPUTMIX,
1615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Vibra class
1620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct iid_vtable VibraDevice_interfaces[] = {
1622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_OBJECT, INTERFACE_OPTIONAL,
1623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mObject)},
1624bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_OPTIONAL,
1625bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mDynamicInterfaceManagement)},
1626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {MPH_VIBRA, INTERFACE_OPTIONAL,
1627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        offsetof(struct VibraDevice_class, mVibra)}
1628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1629bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ VibraDevice_class = {
1631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VibraDevice_interfaces,
1632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(VibraDevice_interfaces)/sizeof(VibraDevice_interfaces[0]),
1633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MPH_to_Vibra,
1634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //"VibraDevice",
1635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    sizeof(struct VibraDevice_class),
1636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SL_OBJECTID_VIBRADEVICE,
1637bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL,
1638bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    NULL
1639bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1640bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Map SL_OBJECTID to class */
1642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ * const classes[] = {
1644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Do not change order of these entries; they are in numerical order
1645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &Engine_class,
1646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &LEDDevice_class,
1647bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &AudioPlayer_class,
1648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &AudioRecorder_class,
1649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &MidiPlayer_class,
1650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &Listener_class,
1651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &_3DGroup_class,
1652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &VibraDevice_class,
1653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &OutputMix_class,
1654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    &MetadataExtractor_class
1655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
1656bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1657bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic const struct class_ *objectIDtoClass(SLuint32 objectID)
1658bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 objectID0 = classes[0]->mObjectID;
1660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (objectID0 <= objectID &&
1661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        classes[sizeof(classes)/sizeof(classes[0])-1]->mObjectID >= objectID)
1662bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return classes[objectID - objectID0];
1663bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return NULL;
1664bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1665bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Construct a new instance of the specified class, exposing selected interfaces
1667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void *construct(const struct class_ *class__, unsigned exposedMask)
1669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1670bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *this;
1671bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this = malloc(class__->mSize);
1673bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1674bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this = calloc(1, class__->mSize);
1675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != this) {
1677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // for debugging, to detect uninitialized fields
1679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        memset(this, 0x55, class__->mSize);
1680bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1681bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        ((struct Object_interface *) this)->mClass = class__;
1682bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        ((struct Object_interface *) this)->mExposedMask = exposedMask;
1683bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        const struct iid_vtable *x = class__->mInterfaces;
1684bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        unsigned i;
1685bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (i = 0; exposedMask; ++i, ++x, exposedMask >>= 1) {
1686bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            if (exposedMask & 1) {
1687bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                unsigned MPH = x->mMPH;
1688bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                size_t offset = x->mOffset;
1689bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                void *self = (char *) this + offset;
1690bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                ((void **) self)[1] = this;
1691bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                VoidHook init = MPH_init_table[MPH].mInit;
1692bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                if (NULL != init)
1693bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    (*init)(self);
1694bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
1695bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
1696bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
1697bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return this;
1698bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1699bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1700bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Interface implementations */
1701bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1702bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME Sort by interface
1703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1704bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Object implementation */
1705bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1706bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_Realize(SLObjectItf self, SLboolean async)
1707bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1708bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME locking needed here in case two threads call Realize at once
1710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_OBJECT_STATE_UNREALIZED != this->mState)
1711bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1712bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = this->mClass;
1713bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    StatusHook realize = class__->mRealize;
1714bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result;
1715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME This should be done asynchronously if requested
1716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    result = NULL != realize ?  (*realize)(this) : SL_RESULT_SUCCESS;
1717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS == result)
1718bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mState = SL_OBJECT_STATE_REALIZED;
1719bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (async && NULL != this->mCallback)
1720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*this->mCallback)(self, this->mContext,
1721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mState, NULL);
1722bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return result;
1723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1724bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_Resume(SLObjectItf self, SLboolean async)
1726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME process async callback
1728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetState(SLObjectItf self, SLuint32 *pState)
1732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pState)
1734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pState = this->mState;
1737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1739bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1740bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetInterface(SLObjectItf self, const SLInterfaceID iid,
1741bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *pInterface)
1742bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == iid || NULL == pInterface)
1744bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_OBJECT_STATE_REALIZED != this->mState)
1747bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1748bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = this->mClass;
1749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int MPH = IID_to_MPH(iid);
1750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (0 > MPH)
1751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
1752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int index = class__->mMPH_to_index[MPH];
1753bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (0 > index)
1754bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
1755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mask = 1 << index;
1756bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (!(this->mExposedMask & mask))
1757bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
1758bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME code review on 2010/04/16
1759bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// I think it is "this->this" instead of "this" at line ### :
1760bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// *(void **)pInterface = (char *) this + class__->mInterfaces[index].offset;
1761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *(void **)pInterface = (char *) this + class__->mInterfaces[index].mOffset;
1762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Should note that interface has been gotten,
1763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // and detect use of ill-gotten interfaces
1764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1766bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1767bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_RegisterCallback(SLObjectItf self,
1768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slObjectCallback callback, void *pContext)
1769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
1772bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
1773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_AbortAsyncOperation(SLObjectItf self)
1777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void Object_Destroy(SLObjectItf self)
1781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_AbortAsyncOperation(self);
1783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = this->mClass;
1785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook destroy = class__->mDestroy;
1786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != destroy)
1787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*destroy)(this);
1788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME call the deinitializer for each currently exposed interface,
1789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // whether it is implicit, explicit, optional, or dynamically added
1790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    memset(this, 0x55, this->mClass->mSize);
17922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
1793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED;
17942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    free(this);
17952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_SetPriority(SLObjectItf self, SLint32 priority,
1798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean preemptable)
1799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1801bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPriority = priority;
1802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreemptable = preemptable;
1803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_GetPriority(SLObjectItf self, SLint32 *pPriority,
1807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pPreemptable)
1808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pPriority || NULL == pPreemptable)
1810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
1812bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPriority = this->mPriority;
1813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPreemptable = this->mPreemptable;
1814bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1816bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Object_SetLossOfControlInterfaces(SLObjectItf self,
1818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled)
1819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
1820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
1821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
1822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
1823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLObjectItf_ Object_ObjectItf = {
1824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Realize,
18252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_Resume,
18262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetState,
18272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetInterface,
18282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_RegisterCallback,
18292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_AbortAsyncOperation,
1830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Object_Destroy,
18312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetPriority,
18322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetPriority,
18332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetLossOfControlInterfaces,
18342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
18352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
1836d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* DynamicInterfaceManagement implementation */
1837d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1838d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_AddInterface(
1839bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLDynamicInterfaceManagementItf self, const SLInterfaceID iid,
1840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean async)
1841d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == iid)
1843bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
1845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
1846bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *thisObject =
1847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Object_interface *) this->this;
1848bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = thisObject->mClass;
1849bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int MPH = IID_to_MPH(iid);
1850bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (0 > MPH)
1851bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
1852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int index = class__->mMPH_to_index[MPH];
1853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (0 > index)
1854bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
1855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mask = 1 << index;
1856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (thisObject->mExposedMask & mask)
1857bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Currently do initialization here, but might be asynchronous
1859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *x = &class__->mInterfaces[index];
1860bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t offset = x->mOffset;
1861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *thisItf = (char *) thisObject + offset;
1862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ?
1863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        class__->mSize : x[1].mOffset) - offset;
1864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// for debugging, to detect uninitialized fields
1866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define FILLER 0x55
1867bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
1868bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define FILLER 0
1869bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    memset(thisItf, FILLER, size);
1871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    ((void **) thisItf)[1] = thisObject;
1872bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook init = MPH_init_table[MPH].mInit;
1873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != init)
1874bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*init)(thisItf);
1875bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    thisObject->mExposedMask |= mask;
1876bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAddedMask |= mask;
1877bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
1878bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (async && NULL != this->mCallback) {
1879bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*this->mCallback)(self, this->mContext,
1880bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            SL_DYNAMIC_ITF_EVENT_RESOURCES_AVAILABLE, result, iid);
1881bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
1882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return result;
1883d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1884d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1885d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RemoveInterface(
1886bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLDynamicInterfaceManagementItf self, const SLInterfaceID iid)
1887d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1888bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == iid)
1889bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1890bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
1891bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
1892bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Object_interface *thisObject =
1893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Object_interface *) this->this;
1894bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = thisObject->mClass;
1895bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int MPH = IID_to_MPH(iid);
1896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (MPH < 0)
1897bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1898bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    int index = class__->mMPH_to_index[MPH];
1899bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (index < 0)
1900bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned mask = 1 << index;
1902bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // disallow removal of non-dynamic interfaces
1903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (!(this->mAddedMask & mask))
1904bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
1905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME Currently do de-initialization here, but might be asynchronous
1906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct iid_vtable *x = &class__->mInterfaces[index];
1907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t offset = x->mOffset;
1908bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    void *thisItf = (char *) thisObject + offset;
1909bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    VoidHook deinit = MPH_init_table[MPH].mDeinit;
1910bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != deinit)
1911bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (*deinit)(thisItf);
1912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    size_t size = ((SLuint32) (index + 1) == class__->mInterfaceCount ?
1913bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        class__->mSize : x[1].mOffset) - offset;
1914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
1915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    memset(thisItf, 0x55, size);
1916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
1917bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    thisObject->mExposedMask &= ~mask;
1918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAddedMask &= ~mask;
1919d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1920d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1921d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1922d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_ResumeInterface(
1923d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
1924d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
1925d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1926d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1927d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1929d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RegisterCallback(
1930d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
1931d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slDynamicInterfaceManagementCallback callback, void *pContext)
1932d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DynamicInterfaceManagement_interface *this =
1934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DynamicInterfaceManagement_interface *) self;
1935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
1936bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
1937d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1938d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1939d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDynamicInterfaceManagementItf_
1941d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenDynamicInterfaceManagement_DynamicInterfaceManagementItf = {
1942d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_AddInterface,
1943d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RemoveInterface,
1944d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_ResumeInterface,
1945d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RegisterCallback
1946d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1947d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1948d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Play implementation */
1949d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1950d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPlayState(SLPlayItf self, SLuint32 state)
1951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1952d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (state) {
1953d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_STOPPED:
1954d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PAUSED:
1955d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PLAYING:
1956d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
1957d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
1958d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1959d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
1960d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
1961d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = state;
19622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_PLAYSTATE_STOPPED == state) {
19632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mPosition = (SLmillisecond) 0;
19642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // this->mPositionSamples = 0;
19652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
1966d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1967d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1968d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1969d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPlayState(SLPlayItf self, SLuint32 *pState)
1970d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1971d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
1972d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1973d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
1974d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
1975d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1976d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1977d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
19782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
1979d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
19802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME: for SNDFILE only, check to see if already know duration
19812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // if so, good, otherwise save position,
19822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // read quickly to end of file, counting frames,
19832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // use sample rate to compute duration, then seek back to current position
19842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
19852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
19862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
19872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMsec = this->mDuration;
1988d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1989d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1990d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
19912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
1992d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
19932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
19942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
19952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
19962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMsec = this->mPosition;
1997bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME convert sample units to time units
19982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // SL_TIME_UNKNOWN == this->mPlay.mPosition = SL_TIME_UNKNOWN;
1999d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2000d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2001d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2002d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_RegisterCallback(SLPlayItf self, slPlayCallback callback,
2003d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *pContext)
2004d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
2007bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
2008d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2009d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2010d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2011d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
2012d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEventFlags = eventFlags;
2015d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2016d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2017d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
20182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetCallbackEventsMask(SLPlayItf self,
20192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pEventFlags)
2020d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2021bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEventFlags)
2022bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2023bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2024bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEventFlags = this->mEventFlags;
2025d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2026d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2027d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2028d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
2029d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2030bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2031bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = mSec;
2032d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2033d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2034d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2035d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_ClearMarkerPosition(SLPlayItf self)
2036d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2038bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mMarkerPosition = 0;
2039d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2040d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2041d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2042d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
2043d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMsec)
2045bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2046bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMsec = this->mMarkerPosition;
2048d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2049d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2050d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2051d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
2052d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2053bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2054bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPositionUpdatePeriod = mSec;
2055d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2056d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2057d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
20582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPositionUpdatePeriod(SLPlayItf self,
20592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pMsec)
2060d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2061bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMsec)
2062bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2063bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
2064bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMsec = this->mPositionUpdatePeriod;
2065d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2066d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2067d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPlayItf_ Play_PlayItf = {
2069d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPlayState,
2070d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPlayState,
2071d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetDuration,
2072d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPosition,
2073d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_RegisterCallback,
2074d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetCallbackEventsMask,
2075d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetCallbackEventsMask,
2076d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetMarkerPosition,
2077d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_ClearMarkerPosition,
2078d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetMarkerPosition,
2079d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPositionUpdatePeriod,
2080d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPositionUpdatePeriod
2081d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2082d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2083d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* BufferQueue implementation */
2084d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2085d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer,
2086d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 size)
2087d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2088d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pBuffer)
2089d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2090d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
2091d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME race condition need mutex
2092d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *oldRear = this->mRear;
2093d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *newRear = oldRear;
2094d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (++newRear == &this->mArray[this->mNumBuffers])
2095d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        newRear = this->mArray;
2096d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (newRear == this->mFront)
2097d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_BUFFER_INSUFFICIENT;
2098d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mBuffer = pBuffer;
2099d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mSize = size;
2100d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mRear = newRear;
21012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ++this->mState.count;
2102d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2103d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2104d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Clear(SLBufferQueueItf self)
2106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
2108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = &this->mArray[0];
2109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRear = &this->mArray[0];
2110d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2111d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2112d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
21132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult BufferQueue_GetState(SLBufferQueueItf self,
21142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLBufferQueueState *pState)
2115d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2116d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
2117d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2118d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
2119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef __cplusplus
2120bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    pState->count = this->mState.count;
2121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    pState->playIndex = this->mState.playIndex;
2122bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#else
2123d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
2124bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
2125d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2126d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2127d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2128d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_RegisterCallback(SLBufferQueueItf self,
2129d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback callback, void *pContext)
2130d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2131d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
2132d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
2133d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
2134d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2135d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2136d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf = {
2138d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Enqueue,
2139d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Clear,
2140d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_GetState,
2141d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_RegisterCallback
2142d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2143d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2144d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Volume implementation */
2145d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2146d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetVolumeLevel(SLVolumeItf self, SLmillibel level)
2147d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2148d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // stet despite warning because MIN and MAX might change, and because
2149d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // some compilers allow a wider int type to be passed as a parameter
21502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((SL_MILLIBEL_MIN <= level) && (SL_MILLIBEL_MAX >= level)))
2151d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2152d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
2153d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mLevel = level;
2154d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2155d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2156d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2157d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
2158d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLevel)
21602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
21622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pLevel = this->mLevel;
2163d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2164d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2165d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
21662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Volume_GetMaxVolumeLevel(SLVolumeItf self,
21672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pMaxLevel)
2168d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMaxLevel)
21702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMaxLevel = SL_MILLIBEL_MAX;
2172d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2173d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2174d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2175d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetMute(SLVolumeItf self, SLboolean mute)
2176d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
21782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mMute = mute;
2179d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2180d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2181d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2182d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetMute(SLVolumeItf self, SLboolean *pMute)
2183d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMute)
21852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
21872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMute = this->mMute;
2188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2189d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2190d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2191d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
2192d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
21932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
21942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEnableStereoPosition = enable;
2195d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2196d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2197d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2198d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_IsEnabledStereoPosition(SLVolumeItf self,
2199d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pEnable)
2200d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
22012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEnable)
22022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
22042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEnable = this->mEnableStereoPosition;
2205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2207d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2208d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetStereoPosition(SLVolumeItf self,
2209d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille stereoPosition)
2210d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
22112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
22122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition)))
22132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStereoPosition = stereoPosition;
2215d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2216d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2217d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetStereoPosition(SLVolumeItf self,
2219d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille *pStereoPosition)
2220d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
22212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pStereoPosition)
22222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
22242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStereoPosition = this->mStereoPosition;
2225d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2226d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2227d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVolumeItf_ Volume_VolumeItf = {
2229d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetVolumeLevel,
2230d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetVolumeLevel,
2231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMaxVolumeLevel,
2232d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetMute,
2233d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMute,
2234d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_EnableStereoPosition,
2235d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_IsEnabledStereoPosition,
2236d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetStereoPosition,
2237d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetStereoPosition
2238d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2239d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2240d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Engine implementation */
2241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2242d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice,
2243d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 deviceID, SLuint32 numInterfaces,
22442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2245d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID)
22472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
2249bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2250bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&LEDDevice_class, numInterfaces,
2251bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
22522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
22532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
22542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct LEDDevice_class *this =
2255bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct LEDDevice_class *) construct(&LEDDevice_class, exposedMask);
22562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
22572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
22582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
2259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDevice = &this->mObject.mItf;
2260d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2261d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2262d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2263d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateVibraDevice(SLEngineItf self,
2264d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces,
2265d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2266d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2267bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID)
22682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
2270bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2271bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&VibraDevice_class, numInterfaces,
2272bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
22732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
22742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
22752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct VibraDevice_class *this =
2276bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct VibraDevice_class *) construct(&VibraDevice_class, exposedMask);
22772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
22782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
22792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
2280bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDevice = &this->mObject.mItf;
2281d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2282d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
2285d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
2286d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2287d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2288d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pPlayer)
2289d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2290d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = NULL;
2291bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2292bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&AudioPlayer_class, numInterfaces,
2293bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
22942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
22952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
2296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // check the audio source and sinks
2297bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME move this to a separate function: check source, check locator, etc.
22982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if ((NULL == pAudioSrc) || (NULL == (SLuint32 *) pAudioSrc->pLocator) ||
22992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (NULL == pAudioSrc->pFormat))
2300d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
23012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
23022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
2303d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numBuffers = 0;
23042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataFormat_PCM *df_pcm = NULL;
23052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = NULL;
23062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
23072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLchar *pathname = NULL;
2308bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
23092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (locatorType) {
2310d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
2311d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
23122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_BufferQueue *dl_bq =
23132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
23142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = dl_bq->numBuffers;
2315d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (0 == numBuffers)
2316d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
23172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
2318d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_PCM:
2319d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            {
23202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
23212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->numChannels) {
2322d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 1:
2323d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 2:
2324d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2325d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2326d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2327d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
23282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->samplesPerSec) {
2329d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 44100:
2330d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2331d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 1 // wrong units for samplesPerSec!
2332d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_SAMPLINGRATE_44_1:
2333d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2334d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
2335d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2336d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2337d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2338d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
23392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->bitsPerSample) {
2340d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_PCMSAMPLEFORMAT_FIXED_16:
2341d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2342d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2343d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2344d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2345d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
23462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->containerSize) {
2347d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 16:
2348d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2349d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
2350d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2351d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2352d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
23532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->channelMask) {
2354d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // needs work
2355d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2356d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2357d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
23582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->endianness) {
2359d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_BYTEORDER_LITTLEENDIAN:
2360d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
2361d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others esp. big and native (new not in spec)
2362d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
2363d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
2364d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
2365d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
2366d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            break;
2367d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_MIME:
2368d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_RESERVED3:
2369d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
2370d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        default:
2371d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
2372d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2373d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2374d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
23752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
2376d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
23772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        {
23782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
23792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLchar *uri = dl_uri->URI;
23802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == uri)
23812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_PARAMETER_INVALID;
23822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (strncmp((const char *) uri, "file:///", 8))
23832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
23842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pathname = &uri[8];
23852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
23862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        case SL_DATAFORMAT_MIME:
23872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            {
23882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLDataFormat_MIME *df_mime =
23892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                (SLDataFormat_MIME *) pAudioSrc->pFormat;
23902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLchar *mimeType = df_mime->mimeType;
23912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL == mimeType)
23922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
23932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLuint32 containerType = df_mime->containerType;
23942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!strcmp((const char *) mimeType, "audio/x-wav"))
23952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                ;
23962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // else if (others)
23972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            //    ;
23982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            else
23992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
24002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (containerType) {
24012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            case SL_CONTAINERTYPE_WAV:
24022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                break;
24032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // others
24042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            default:
24052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
24062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
24072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
24082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
24092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        default:
24102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
24112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
24122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME magic number, should be configurable
24132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = 2;
24142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
24152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
2416bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
24172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_ADDRESS:
24182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_IODEVICE:
24192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
24202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED5:
24212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
24222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED8:
24232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
2424d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
2425d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2426d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // check sink, again this should be a separate function
2428d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pAudioSnk || (NULL == (SLuint32 *) pAudioSnk->pLocator))
2429d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2430d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (*(SLuint32 *)pAudioSnk->pLocator) {
2431d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
2432d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
24332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // pAudioSnk->pFormat is ignored
24342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_OutputMix *dl_outmix =
24352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_OutputMix *) pAudioSnk->pLocator;
24362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLObjectItf outputMix = dl_outmix->outputMix;
2437d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME make this an operation on Object: GetClass
24382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if ((NULL == outputMix) || (&OutputMix_class !=
24392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            ((struct Object_interface *) outputMix)->mClass))
2440d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
24412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct OutputMix_interface *om =
24422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            &((struct OutputMix_class *) outputMix)->mOutputMix;
24432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // allocate an entry within OutputMix for this track
24442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME O(n)
24452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned i;
24462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        for (i = 0, track = &om->mTracks[0]; i < 32; ++i, ++track) {
24472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (om->mActiveMask & (1 << i))
24482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
24492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            om->mActiveMask |= 1 << i;
24502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
24512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
24522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (32 <= i) {
24532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME Need a better error code for all slots full in output mix
24542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_MEMORY_FAILURE;
24552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
2456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME replace the above for Android - do not use our own mixer!
2457d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
2458d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
2459d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
2460d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
2461d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_ADDRESS:
2462d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_IODEVICE:
2463d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED5:
2464d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
2465d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED8:
2466d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
2467d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
2468d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2469d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // Construct our new instance
2471d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct AudioPlayer_class *this =
2472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioPlayer_class *) construct(&AudioPlayer_class, exposedMask);
24732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
2474d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
2475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#if 0
2476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mObject.mItf = &AudioPlayer_ObjectItf; // take note!
2477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif
24782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME numBuffers is unavailable for URL, must make a default !
2479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(0 < numBuffers);
2480d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mNumBuffers = numBuffers;
2481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // inline allocation of circular mArray, up to a typical max
2482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (BUFFER_HEADER_TYPICAL >= numBuffers) {
2483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
2484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    } else {
2485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        // FIXME integer overflow possible during multiplication
2486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        this->mBufferQueue.mArray = (struct BufferHeader *)
2487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            malloc((numBuffers + 1) * sizeof(struct BufferHeader));
2488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        if (NULL == this->mBufferQueue.mArray) {
2489bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            free(this);
2490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            return SL_RESULT_MEMORY_FAILURE;
2491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
2492bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
2493d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mFront = this->mBufferQueue.mArray;
2494d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mRear = this->mBufferQueue.mArray;
24952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
24962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mPathname = pathname;
24972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mIs0 = SL_BOOLEAN_TRUE;
2498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef NDEBUG
2499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mSndFile.mSNDFILE = NULL;
25002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetryBuffer = NULL;
25012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetrySize = 0;
25022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
2503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SNDFILE
2504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // link track to player (NOT for Android!!)
25052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mDfPcm = df_pcm;
25062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mBufferQueue = &this->mBufferQueue;
2507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    track->mPlay = &this->mPlay;
2508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // next 2 fields must be initialized explicitly (not part of this)
25092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mReader = NULL;
25102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mAvail = 0;
25112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new audio player object
2512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPlayer = &this->mObject.mItf;
2513d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2514d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2515d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioRecorder(SLEngineItf self,
2517d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk,
2518d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2519d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2520d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pRecorder)
2522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pRecorder = NULL;
2524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&AudioRecorder_class, numInterfaces,
2526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2529d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2530d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2531d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2532d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
2533d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
2534d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
2535d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
2536d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
25372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pPlayer)
25382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
25392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pPlayer = NULL;
2540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&MidiPlayer_class, numInterfaces,
2542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
25432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
25442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
25452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMIDISrc || NULL == pAudioOutput)
25462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
25472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MidiPlayer_class *this =
2548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct MidiPlayer_class *) construct(&MidiPlayer_class, exposedMask);
25492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
25502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
25512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new MIDI player object
2552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPlayer = &this->mObject.mItf;
2553d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2554d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2555d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2556d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
2557d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2558d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2559d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2560bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pListener)
2561bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2562bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pListener = NULL;
2563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&Listener_class, numInterfaces,
2565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2569d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2570d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2571d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup,
2572d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2573d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2574d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pGroup)
2576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pGroup = NULL;
2578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&_3DGroup_class, numInterfaces,
2580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2581bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2584d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2585d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2586d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix,
2587d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2588d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2589d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2590d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pMix)
2591d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2592bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMix = NULL;
2593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&OutputMix_class, numInterfaces,
2595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2596d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
2597d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
2598d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct OutputMix_class *this =
2599bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct OutputMix_class *) construct(&OutputMix_class, exposedMask);
2600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
2601d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
2602bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMix = &this->mObject.mItf;
2603d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2605d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2606d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMetadataExtractor(SLEngineItf self,
2607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource,
2608d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2609d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2610d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMetadataExtractor)
2612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMetadataExtractor = NULL;
2614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
2615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&MetadataExtractor_class, numInterfaces,
2616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
2617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (SL_RESULT_SUCCESS != result)
2618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return result;
2619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct MetadataExtractor_class *this = (struct MetadataExtractor_class *)
2620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        construct(&MetadataExtractor_class, exposedMask);
2621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
2622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
2623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pMetadataExtractor = &this->mObject.mItf;
2624d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2625d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2626d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2627d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateExtensionObject(SLEngineItf self,
2628d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pObject, void *pParameters, SLuint32 objectID,
2629d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2630d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
2631d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pObject)
2633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pObject = NULL;
2635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
2636d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2637d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2638d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedInterfaces(SLEngineItf self,
2639d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
2640d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumSupportedInterfaces)
2642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const struct class_ *class__ = objectIDtoClass(objectID);
2644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == class__)
2645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_FEATURE_UNSUPPORTED;
2646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumSupportedInterfaces = class__->mInterfaceCount;
2647d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2648d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2649d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Engine_QuerySupportedInterfaces(SLEngineItf self,
2651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
2652d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2653d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2654d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2655d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedExtensions(SLEngineItf self,
2657d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 *pNumExtensions)
2658d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumExtensions)
2660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumExtensions = 0;
2662d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2663d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2664d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2665d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QuerySupportedExtension(SLEngineItf self,
2666d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
2667d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // any index >= 0 will be >= number of supported extensions
2669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_PARAMETER_INVALID;
2670d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2672d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_IsExtensionSupported(SLEngineItf self,
2673d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLchar *pExtensionName, SLboolean *pSupported)
2674d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pExtensionName || NULL == pSupported)
2676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_FALSE;
2678d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2679d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2680d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2681bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEngineItf_ Engine_EngineItf = {
2682d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateLEDDevice,
2683d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateVibraDevice,
2684d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioPlayer,
2685d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioRecorder,
2686d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMidiPlayer,
2687d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateListener,
2688d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_Create3DGroup,
2689d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateOutputMix,
2690d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMetadataExtractor,
2691d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateExtensionObject,
2692d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedInterfaces,
2693d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedInterfaces,
2694d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedExtensions,
2695d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedExtension,
2696d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_IsExtensionSupported
2697d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
2698d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
26992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioIODeviceCapabilities implementation */
2700d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
27012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioInputs(
27022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumInputs,
27032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pInputDeviceIDs)
2704d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
27052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioInputCapabilities(
27092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
27102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioInputDescriptor *pDescriptor)
27112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
27162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback(
27172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
27182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioInputsChangedCallback callback, void *pContext)
27192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioOutputs(
27242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumOutputs,
27252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
27262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumOutputs)
2728d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pOutputDeviceIDs) {
27302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME should be OEM-configurable
27312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (2 > *pNumOutputs)
27322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_BUFFER_INSUFFICIENT;
27332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[0] = DEVICE_ID_HEADSET;
27342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[1] = DEVICE_ID_HANDSFREE;
27352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
27362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNumOutputs = 2;
27372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioOutputCapabilities(
27412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
27422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioOutputDescriptor *pDescriptor)
27432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDescriptor)
2745d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (deviceID) {
27472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME should be OEM-configurable
27482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HEADSET:
27492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_headset;
27502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
27512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HANDSFREE:
27522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_handsfree;
27532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
27542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
27552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_IO_ERROR;
2756d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
2757d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
2758d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2759d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
27602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
27612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback(
27622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
27632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioOutputsChangedCallback callback, void *pContext)
2764d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
27652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult
2769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback(
27702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
27712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slDefaultDeviceIDMapChangedCallback callback, void *pContext)
27722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioInputs(
27772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
27782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioInputs, SLuint32 *pAudioInputDeviceIDs)
27792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioOutputs(
27842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
27852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioOutputs, SLuint32 *pAudioOutputDeviceIDs)
27862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetDefaultAudioDevices(
27912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 defaultDeviceID,
27922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioDevices, SLuint32 *pAudioDeviceIDs)
27932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QuerySampleFormatsSupported(
27982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
27992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmilliHertz samplingRate, SLint32 *pSampleFormats,
28002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumOfSampleFormats)
28012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
28042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioIODeviceCapabilitiesItf_
28062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf = {
28072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioInputs,
28082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioInputCapabilities,
28092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback,
28102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioOutputs,
28112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioOutputCapabilities,
28122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback,
28132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback,
28142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioInputs,
28152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioOutputs,
28162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetDefaultAudioDevices,
28172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QuerySampleFormatsSupported
28182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
28192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* OutputMix implementation */
28212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_GetDestinationOutputDeviceIDs(SLOutputMixItf self,
28232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten   SLint32 *pNumDevices, SLuint32 *pDeviceIDs)
28242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
28272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_RegisterDeviceChangeCallback(SLOutputMixItf self,
28292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slMixDeviceChangeCallback callback, void *pContext)
28302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
28332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_ReRoute(SLOutputMixItf self, SLint32 numOutputDevices,
28352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
28362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
28392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLOutputMixItf_ OutputMix_OutputMixItf = {
28412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_GetDestinationOutputDeviceIDs,
28422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_RegisterDeviceChangeCallback,
28432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_ReRoute
28442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
28452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Seek implementation */
28472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetPosition(SLSeekItf self, SLmillisecond pos,
28492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 seekMode)
28502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (seekMode) {
28522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_FAST:
28532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_ACCURATE:
28542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
28552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
2856d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
28572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
28582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
28592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPos = pos;
28602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
2861d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2862d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
28632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetLoop(SLSeekItf self, SLboolean loopEnable,
28642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond startPos, SLmillisecond endPos)
2865d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
28662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
28672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mLoopEnabled = loopEnable;
28682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStartPos = startPos;
28692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEndPos = endPos;
28702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
28722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
28732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
28742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pStartPos, SLmillisecond *pEndPos)
28752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
28762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos)
2877d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
28782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
28792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pLoopEnabled = this->mLoopEnabled;
28802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStartPos = this->mStartPos;
28812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEndPos = this->mEndPos;
28822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
2883d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2884d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2885bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLSeekItf_ Seek_SeekItf = {
28862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetPosition,
28872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetLoop,
28882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_GetLoop
28892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2890d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
28912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DCommit implementation */
2892d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
28932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_Commit(SL3DCommitItf self)
2894d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
28952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
28962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
2897d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
28982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_SetDeferred(SL3DCommitItf self, SLboolean deferred)
28992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2900bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DCommit_interface *this = (struct _3DCommit_interface *) self;
2901bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDeferred = deferred;
29022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
2903d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
2904d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DCommitItf_ _3DCommit_3DCommitItf = {
29062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_Commit,
29072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_SetDeferred
29082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
29092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DDoppler implementation */
29112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetVelocityCartesian(SL3DDopplerItf self,
29132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pVelocity)
2914d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
2915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVelocity)
2916bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2917bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
2918bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mCartesian = *pVelocity;
29192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
2921d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2922bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetVelocitySpherical(SL3DDopplerItf self,
29232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter speed)
29242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2925bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
2926bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mAzimuth = azimuth;
2927bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mElevation = elevation;
2928bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVelocity.mSpherical.mSpeed = speed;
29292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
2931d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2932bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_GetVelocityCartesian(SL3DDopplerItf self,
29332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pVelocity)
29342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVelocity)
2936bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2937bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
2938bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pVelocity = this->mVelocity.mCartesian;
29392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_SetDopplerFactor(SL3DDopplerItf self,
29432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille dopplerFactor)
29442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2945bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
2946bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mDopplerFactor = dopplerFactor;
29472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DDoppler_GetDopplerFactor(SL3DDopplerItf self,
2951bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pDopplerFactor)
29522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2953bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pDopplerFactor)
2954bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DDoppler_interface *this = (struct _3DDoppler_interface *) self;
2956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pDopplerFactor = this->mDopplerFactor;
29572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2960bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DDopplerItf_ _3DDoppler_3DDopplerItf = {
2961bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetVelocityCartesian,
2962bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetVelocitySpherical,
2963bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_GetVelocityCartesian,
2964bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_SetDopplerFactor,
2965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DDoppler_GetDopplerFactor
29662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
29672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DLocation implementation */
29692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationCartesian(SL3DLocationItf self,
29712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pLocation)
29722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pLocation)
2974bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2975bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
2976bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian = *pLocation;
29772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationSpherical(SL3DLocationItf self,
29812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance)
29822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2983bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
2984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mAzimuth = azimuth;
2985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mElevation = elevation;
2986bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mSpherical.mDistance = distance;
29872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
2988d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
29892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement)
29912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
2992bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pMovement)
2993bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2994bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
2995bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.x += pMovement->x;
2996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.y += pMovement->y;
2997bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLocation.mCartesian.z += pMovement->z;
29982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
29992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetLocationCartesian(SL3DLocationItf self,
30022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pLocation)
30032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3004bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pLocation)
3005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3007bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pLocation = this->mLocation.mCartesian;
30082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationVectors(SL3DLocationItf self,
30122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pFront, const SLVec3D *pAbove)
30132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pFront || NULL == pAbove)
3015bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3016bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mFront = *pFront;
3018bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mAbove = *pAbove;
30192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationAngles(SL3DLocationItf self,
30232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
30242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3025bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mHeading = heading;
3027bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPitch = pitch;
3028bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRoll = roll;
30292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta,
30332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pAxis)
30342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3035bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pAxis)
3036bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
30372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetOrientationVectors(SL3DLocationItf self,
30412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pFront, SLVec3D *pUp)
30422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3043bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pFront || NULL == pUp)
3044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3045bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DLocation_interface *this = (struct _3DLocation_interface *) self;
3046bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pFront = this->mFront;
3047bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pUp = this->mUp;
30482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3051bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DLocationItf_ _3DLocation_3DLocationItf = {
30522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationCartesian,
30532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationSpherical,
30542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Move,
30552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetLocationCartesian,
30562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationVectors,
30572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationAngles,
30582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Rotate,
30592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetOrientationVectors
30602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
30612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioDecoderCapabilities implementation */
30632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should build this table from Caps table below
30652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLuint32 Our_Decoder_IDs[] = {
30662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_PCM,
30672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_MP3,
30682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMR,
30692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWB,
30702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWBPLUS,
30712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AAC,
30722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_WMA,
30732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_REAL,
30742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME not in 1.0.1 header file
30752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define SL_AUDIOCODEC_VORBIS   ((SLuint32) 0x00000009)
30762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_VORBIS
30772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
30782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define MAX_DECODERS (sizeof(Our_Decoder_IDs) / sizeof(Our_Decoder_IDs[0]))
30792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoders(
30812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 *pNumDecoders,
30822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pDecoderIds)
30832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
30842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumDecoders)
30852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
30862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDecoderIds)
30872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumDecoders = MAX_DECODERS;
30882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    else {
30892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 numDecoders = *pNumDecoders;
30902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (MAX_DECODERS < numDecoders) {
30912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            numDecoders = MAX_DECODERS;
30922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            *pNumDecoders = MAX_DECODERS;
30932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
30942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memcpy(pDecoderIds, Our_Decoder_IDs, numDecoders * sizeof(SLuint32));
30952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
30962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
30972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
30982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
30992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLmilliHertz Sample_Rates_PCM[] = {
31002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,
31012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_11_025,
31022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_12,
31032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_16,
31042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_22_05,
31052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_24,
31062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_32,
31072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
31082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48
31092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioCodecDescriptor Caps_PCM[] = {
31122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {
31132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2,                   // maxChannels
31142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    8,                   // minBitsPerSample
31152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    16,                  // maxBitsPerSample
31162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,   // minSampleRate
31172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48,  // maxSampleRate
31182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,    // isFreqRangeContinuous
31192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLmilliHertz *) Sample_Rates_PCM,
31202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // pSampleRatesSupported;
31212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(Sample_Rates_PCM)/sizeof(Sample_Rates_PCM[0]),
31222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // numSampleRatesSupported
31232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    1,                   // minBitRate
31242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ~0,                  // maxBitRate
31252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,     // isBitrateRangeContinuous
31262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,                // pBitratesSupported
31272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,                   // numBitratesSupported
31282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOPROFILE_PCM, // profileSetting
31292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0                    // modeSetting
31302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
31312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct AudioDecoderCapabilities {
31342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mDecoderID;
31352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mNumCapabilities;
31362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLAudioCodecDescriptor *mDescriptors;
31372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten} Our_Decoder_Capabilities[] = {
3138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#define ENTRY(x) \
3139bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    {SL_AUDIOCODEC_##x, sizeof(Caps_##x)/sizeof(Caps_##x[0]), Caps_##x}
31402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(PCM)
31412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#if 0
31422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(MP3),
31432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMR),
31442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWB),
31452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWBPLUS),
31462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AAC),
31472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(WMA),
31482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(REAL),
31492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(VORBIS)
31502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
31512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoderCapabilities(
31542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 decoderId, SLuint32 *pIndex,
31552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
31562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
31572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3160bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioDecoderCapabilitiesItf_
31612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_AudioDecoderCapabilitiesItf = {
31622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoders,
31632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoderCapabilities
31642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoder implementation */
31672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_SetEncoderSettings(SLAudioEncoderItf self,
31692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings  *pSettings)
31702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3171bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSettings)
3172bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoder_interface *this =
3174bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoder_interface *) self;
3175bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mSettings = *pSettings;
31762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_GetEncoderSettings(SLAudioEncoderItf self,
31802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings *pSettings)
31812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3182bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSettings)
3183bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3184bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct AudioEncoder_interface *this =
3185bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct AudioEncoder_interface *) self;
3186bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSettings = this->mSettings;
31872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
31882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
31892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3190bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioEncoderItf_ AudioEncoder_AudioEncoderItf = {
31912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_SetEncoderSettings,
31922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_GetEncoderSettings
31932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
31942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoderCapabilities implementation */
31962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
31972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoders(
3198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 *pNumEncoders,
3199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEncoderIds)
32002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoderCapabilities(
32052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 encoderId, SLuint32 *pIndex,
32062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
32072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3211bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLAudioEncoderCapabilitiesItf_
32122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_AudioEncoderCapabilitiesItf = {
32132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoders,
32142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoderCapabilities
32152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
32162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DeviceVolume implementation */
32182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolumeScale(SLDeviceVolumeItf self,
32202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pMinValue, SLint32 *pMaxValue,
32212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsMillibelScale)
32222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMinValue)
32242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMinValue = 0;
32252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMaxValue)
32262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMaxValue = 10;
32272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsMillibelScale)
32282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsMillibelScale = SL_BOOLEAN_FALSE;
32292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_SetVolume(SLDeviceVolumeItf self,
32332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 volume)
32342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
3236bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
3237bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mVolume = volume;
32382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolume(SLDeviceVolumeItf self,
32422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pVolume)
32432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3244bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pVolume)
3245bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3246bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct DeviceVolume_interface *this =
3247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct DeviceVolume_interface *) self;
3248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pVolume = this->mVolume;
32492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3252bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf = {
32532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolumeScale,
32542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_SetVolume,
32552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolume
32562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
32572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DynamicSource implementation */
32592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DynamicSource_SetSource(SLDynamicSourceItf self,
32612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataSource *pDataSource)
32622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLDynamicSourceItf_ DynamicSource_DynamicSourceItf = {
32672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DynamicSource_SetSource
32682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
32692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EffectSend implementation */
32712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_EnableEffectSend(SLEffectSendItf self,
32732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
32742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_IsEnabled(SLEffectSendItf self,
32792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
32802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetDirectLevel(SLEffectSendItf self,
32852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel directLevel)
32862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetDirectLevel(SLEffectSendItf self,
32912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pDirectLevel)
32922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
32942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
32952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
32962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetSendLevel(SLEffectSendItf self,
32972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel sendLevel)
32982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
32992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetSendLevel(SLEffectSendItf self,
33032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel *pSendLevel)
33042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3308bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEffectSendItf_ EffectSend_EffectSendItf = {
33092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_EnableEffectSend,
33102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_IsEnabled,
33112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetDirectLevel,
33122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetDirectLevel,
33132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetSendLevel,
33142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetSendLevel
33152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
33162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EngineCapabilities implementation */
33182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QuerySupportedProfiles(
33202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported)
33212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pProfilesSupported)
33232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME This is pessimistic as it omits the unofficial driver profile
3325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // SL_PROFILES_PHONE | SL_PROFILES_MUSIC | SL_PROFILES_GAME
3326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pProfilesSupported = 0;
33272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAvailableVoices(
33312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 voiceType, SLint16 *pNumMaxVoices,
33322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices)
33332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (voiceType) {
33352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_2D_AUDIO:
33362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_MIDI:
33372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_AUDIO:
33382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_MIDIOUTPUT:
33392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
33402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
33412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
33432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumMaxVoices)
33442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumMaxVoices = 0;
33452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsAbsoluteMax)
33462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsAbsoluteMax = SL_BOOLEAN_TRUE;
33472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumFreeVoices)
33482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumFreeVoices = 0;
33492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryNumberOfMIDISynthesizers(
33532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLint16 *pNum)
33542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNum)
33562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNum = 0;
33582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self,
33622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep)
33632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!(NULL != pMajor && NULL != pMinor && NULL != pStep))
33652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMajor = 1;
33672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMinor = 0;
33682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStep = 1;
33692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryLEDCapabilities(
33732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pLEDDeviceID,
33742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLLEDDescriptor *pDescriptor)
33752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryVibraCapabilities(
33802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pVibraDeviceID,
33812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVibraDescriptor *pDescriptor)
33822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
33862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self,
33872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsThreadSafe)
33882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
33892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pIsThreadSafe)
33902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
33912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME For now
33922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pIsThreadSafe = SL_BOOLEAN_FALSE;
33932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
33942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
33952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEngineCapabilitiesItf_
33972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_EngineCapabilitiesItf = {
33982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QuerySupportedProfiles,
33992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAvailableVoices,
34002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryNumberOfMIDISynthesizers,
34012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAPIVersion,
34022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryLEDCapabilities,
34032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryVibraCapabilities,
34042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_IsThreadSafe
34052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
34062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3407bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* LEDArray implementation */
3408bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_ActivateLEDArray(SLLEDArrayItf self,
3410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 lightMask)
3411bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3412bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3413bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_IsLEDArrayActivated(SLLEDArrayItf self,
3416bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *lightMask)
3417bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3418bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3419bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_SetColor(SLLEDArrayItf self, SLuint8 index,
3422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLHSL *color)
3423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3424bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3426bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult LEDArray_GetColor(SLLEDArrayItf self, SLuint8 index,
3428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLHSL *color)
3429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3432bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3433bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLLEDArrayItf_ LEDArray_LEDArrayItf = {
3434bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_ActivateLEDArray,
3435bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_IsLEDArrayActivated,
3436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_SetColor,
3437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    LEDArray_GetColor,
3438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3439bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3440bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MetadataExtraction implementation */
3441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3442bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetItemCount(SLMetadataExtractionItf self,
3443bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pItemCount)
3444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetKeySize(SLMetadataExtractionItf self,
3449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 *pKeySize)
3450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3451bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3452bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3453bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3454bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetKey(SLMetadataExtractionItf self,
3455bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 keySize, SLMetadataInfo *pKey)
3456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3458bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3459bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3460bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetValueSize(SLMetadataExtractionItf self,
3461bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 *pValueSize)
3462bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3463bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3466bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_GetValue(SLMetadataExtractionItf self,
3467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLuint32 valueSize, SLMetadataInfo *pValue)
3468bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3471bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_AddKeyFilter(SLMetadataExtractionItf self,
3473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 keySize, const void *pKey, SLuint32 keyEncoding,
3474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLchar *pValueLangCountry, SLuint32 valueEncoding, SLuint8 filterMask)
3475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3478bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataExtraction_ClearKeyFilter(SLMetadataExtractionItf self)
3480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMetadataExtractionItf_
3485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_MetadataExtractionItf = {
3486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetItemCount,
3487bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetKeySize,
3488bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetKey,
3489bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetValueSize,
3490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_GetValue,
3491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_AddKeyFilter,
3492bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataExtraction_ClearKeyFilter
3493bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3494bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3495bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MetadataTraversal implementation */
3496bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3497bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_SetMode(SLMetadataTraversalItf self,
3498bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 mode)
3499bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3500bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3501bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3503bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildCount(SLMetadataTraversalItf self,
3504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pCount)
3505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3506bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3507bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3508bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3509bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildMIMETypeSize(
3510bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLMetadataTraversalItf self, SLuint32 index, SLuint32 *pSize)
3511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3514bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_GetChildInfo(SLMetadataTraversalItf self,
3516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index, SLint32 *pNodeID, SLuint32 *pType, SLuint32 size,
3517bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLchar *pMimeType)
3518bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3519bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MetadataTraversal_SetActiveNode(SLMetadataTraversalItf self,
3523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 index)
3524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3526bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMetadataTraversalItf_
3529bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_MetadataTraversalItf = {
3530bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_SetMode,
3531bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildCount,
3532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildMIMETypeSize,
3533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_GetChildInfo,
3534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MetadataTraversal_SetActiveNode
3535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3536bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3537bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* MuteSolo implementation */
3538bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3539bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan,
3540bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten   SLboolean mute)
3541bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3542bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3543bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3544bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3545bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan,
3546bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pMute)
3547bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3548bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3549bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3550bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3551bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
3552bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean solo)
3553bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3554bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3555bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3556bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3557bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
3558bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSolo)
3559bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3560bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3561bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3562bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3563bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult MuteSolo_GetNumChannels(SLMuteSoloItf self,
3564bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint8 *pNumChannels)
3565bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3566bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3567bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3568bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3569bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLMuteSoloItf_ MuteSolo_MuteSoloItf = {
3570bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_SetChannelMute,
3571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetChannelMute,
3572bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_SetChannelSolo,
3573bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetChannelSolo,
3574bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    MuteSolo_GetNumChannels
3575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3576bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3577bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Pitch implementation */
3578bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3579bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_SetPitch(SLPitchItf self, SLpermille pitch)
3580bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3581bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3582bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3583bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3584bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_GetPitch(SLPitchItf self, SLpermille *pPitch)
3585bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3586bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3587bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3588bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3589bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Pitch_GetPitchCapabilities(SLPitchItf self,
3590bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinPitch, SLpermille *pMaxPitch)
3591bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3592bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3593bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3594bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPitchItf_ Pitch_PitchItf = {
3596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_SetPitch,
3597bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_GetPitch,
3598bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Pitch_GetPitchCapabilities
3599bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3600bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3601bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* PlaybackRate implementation */
3602bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3603bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate)
3604bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3605bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3606bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3607bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3608bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate)
3609bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3610bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3611bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3612bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3613bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self,
3614bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 constraints)
3615bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3616bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3617bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3618bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3619bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetProperties(SLPlaybackRateItf self,
3620bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pProperties)
3621bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3622bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3624bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3625bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self,
3626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille rate, SLuint32 *pCapabilities)
3627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3629bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3630bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index,
3632bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize,
3633bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pCapabilities)
3634bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3635bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3636bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3637bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3638bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPlaybackRateItf_ PlaybackRate_PlaybackRateItf = {
3639bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_SetRate,
3640bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetRate,
3641bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_SetPropertyConstraints,
3642bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetProperties,
3643bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetCapabilitiesOfRate,
3644bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PlaybackRate_GetRateRange
3645bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3646bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3647bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* PrefetchStatus implementation */
3648bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3649bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetPrefetchStatus(SLPrefetchStatusItf self,
3650bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pStatus)
3651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetFillLevel(SLPrefetchStatusItf self,
3656bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pLevel)
3657bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3658bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3661bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_RegisterCallback(SLPrefetchStatusItf self,
3662bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slPrefetchCallback callback, void *pContext)
3663bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3664bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3665bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_SetCallbackEventsMask(SLPrefetchStatusItf self,
3668bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 eventFlags)
3669bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3670bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3671bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3673bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetCallbackEventsMask(SLPrefetchStatusItf self,
3674bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEventFlags)
3675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_SetFillUpdatePeriod(SLPrefetchStatusItf self,
3680bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille period)
3681bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3682bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3683bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3684bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3685bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PrefetchStatus_GetFillUpdatePeriod(SLPrefetchStatusItf self,
3686bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pPeriod)
3687bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3688bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3689bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3690bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3691bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPrefetchStatusItf_
3692bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn KastenPrefetchStatus_PrefetchStatusItf = {
3693bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetPrefetchStatus,
3694bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetFillLevel,
3695bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_RegisterCallback,
3696bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_SetCallbackEventsMask,
3697bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetCallbackEventsMask,
3698bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_SetFillUpdatePeriod,
3699bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PrefetchStatus_GetFillUpdatePeriod
3700bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3701bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3702bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* RatePitch implementation */
3703bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3704bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_SetRate(SLRatePitchItf self, SLpermille rate)
3705bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3706bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3707bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3708bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3709bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_GetRate(SLRatePitchItf self, SLpermille *pRate)
3710bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3711bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3712bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3713bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3714bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult RatePitch_GetRatePitchCapabilities(SLRatePitchItf self,
3715bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate)
3716bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3717bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3718bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3719bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3720bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLRatePitchItf_ RatePitch_RatePitchItf = {
3721bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_SetRate,
3722bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_GetRate,
3723bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    RatePitch_GetRatePitchCapabilities
3724bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3725bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3726bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Record implementation */
3727bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3728bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetRecordState(SLRecordItf self, SLuint32 state)
3729bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3730bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3731bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3732bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3733bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetRecordState(SLRecordItf self, SLuint32 *pState)
3734bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3735bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3736bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3737bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3738bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetDurationLimit(SLRecordItf self, SLmillisecond msec)
3739bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3740bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3741bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3742bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3743bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetPosition(SLRecordItf self, SLmillisecond *pMsec)
3744bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3745bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3746bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3747bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3748bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_RegisterCallback(SLRecordItf self,
3749bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    slRecordCallback callback, void *pContext)
3750bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3751bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3752bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3753bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3754bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetCallbackEventsMask(SLRecordItf self,
3755bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 eventFlags)
3756bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3757bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3758bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3759bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3760bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetCallbackEventsMask(SLRecordItf self,
3761bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 *pEventFlags)
3762bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3763bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3764bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3765bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3766bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetMarkerPosition(SLRecordItf self, SLmillisecond mSec)
3767bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3768bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3769bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3770bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3771bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_ClearMarkerPosition(SLRecordItf self)
3772bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3773bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3774bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3775bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3776bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec)
3777bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3778bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3779bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3780bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3781bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_SetPositionUpdatePeriod(SLRecordItf self,
3782bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond mSec)
3783bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3784bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3785bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3786bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3787bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Record_GetPositionUpdatePeriod(SLRecordItf self,
3788bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillisecond *pMsec)
3789bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3790bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3791bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3792bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3793bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLRecordItf_ Record_RecordItf = {
3794bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetRecordState,
3795bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetRecordState,
3796bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetDurationLimit,
3797bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetPosition,
3798bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_RegisterCallback,
3799bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetCallbackEventsMask,
3800bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetCallbackEventsMask,
3801bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetMarkerPosition,
3802bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_ClearMarkerPosition,
3803bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetMarkerPosition,
3804bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_SetPositionUpdatePeriod,
3805bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Record_GetPositionUpdatePeriod
3806bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3807bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3808bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* ThreadSync implementation */
3809bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3810bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult ThreadSync_EnterCriticalSection(SLThreadSyncItf self)
3811bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3812bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3813bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3814bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3815bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult ThreadSync_ExitCriticalSection(SLThreadSyncItf self)
3816bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3817bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3818bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3819bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3820bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf = {
3821bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    ThreadSync_EnterCriticalSection,
3822bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    ThreadSync_ExitCriticalSection
3823bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3824bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3825bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Vibra implementation */
3826bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3827bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_Vibrate(SLVibraItf self, SLboolean vibrate)
3828bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3829bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3830bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3831bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3832bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_IsVibrating(SLVibraItf self, SLboolean *pVibrating)
3833bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3834bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3835bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3836bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3837bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_SetFrequency(SLVibraItf self, SLmilliHertz frequency)
3838bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3839bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3840bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3841bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3842bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_GetFrequency(SLVibraItf self, SLmilliHertz *pFrequency)
3843bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3844bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3845bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3846bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3847bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_SetIntensity(SLVibraItf self, SLpermille intensity)
3848bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3849bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3850bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3851bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3852bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Vibra_GetIntensity(SLVibraItf self, SLpermille *pIntensity)
3853bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3854bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3855bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3856bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3857bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVibraItf_ Vibra_VibraItf = {
3858bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_Vibrate,
3859bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_IsVibrating,
3860bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_SetFrequency,
3861bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_GetFrequency,
3862bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_SetIntensity,
3863bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Vibra_GetIntensity
3864bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3865bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3866bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Visualization implementation */
3867bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3868bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Visualization_RegisterVisualizationCallback(
3869bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVisualizationItf self, slVisualizationCallback callback, void *pContext,
3870bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz rate)
3871bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3872bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Visualization_interface *this =
3873bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Visualization_interface *) self;
3874bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mCallback = callback;
3875bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mContext = pContext;
3876bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mRate = rate;
3877bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3878bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3879bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3880bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Visualization_GetMaxRate(SLVisualizationItf self,
3881bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pRate)
3882bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3883bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pRate)
3884bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3885bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pRate = 0;
3886bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3887bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3888bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3889bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVisualizationItf_ Visualization_VisualizationItf = {
3890bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Visualization_RegisterVisualizationCallback,
3891bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Visualization_GetMaxRate
3892bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3893bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3894bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* BassBoost implementation */
38952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3896bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_SetEnabled(SLBassBoostItf self, SLboolean enabled)
38972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3898bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
3899bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnabled = enabled;
39002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3903bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_IsEnabled(SLBassBoostItf self, SLboolean *pEnabled)
39042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3905bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEnabled)
3906bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3907bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
3908bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEnabled = this->mEnabled;
39092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3912bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_SetStrength(SLBassBoostItf self, SLpermille strength)
39132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3914bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
3915bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStrength = strength;
39162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3919bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_GetRoundedStrength(SLBassBoostItf self,
3920bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pStrength)
39212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3922bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pStrength)
3923bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3924bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct BassBoost_interface *this = (struct BassBoost_interface *) self;
3925bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pStrength = this->mStrength;
39262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3929bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult BassBoost_IsStrengthSupported(SLBassBoostItf self,
3930bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSupported)
3931bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
3932bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSupported)
3933bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3934bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_TRUE;
3935bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
3936bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
3937bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3938bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLBassBoostItf_ BassBoost_BassBoostItf = {
3939bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_SetEnabled,
3940bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_IsEnabled,
3941bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_SetStrength,
3942bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_GetRoundedStrength,
3943bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    BassBoost_IsStrengthSupported
39442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
39452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3946bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DGrouping implementation */
39472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3948bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DGrouping_Set3DGroup(SL3DGroupingItf self, SLObjectItf group)
39492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3950bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self;
3951bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mGroup = group;
39522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3955bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DGrouping_Get3DGroup(SL3DGroupingItf self,
3956bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLObjectItf *pGroup)
39572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
3958bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pGroup)
3959bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
3960bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct _3DGrouping_interface *this = (struct _3DGrouping_interface *) self;
3961bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pGroup = this->mGroup;
39622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3965bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DGroupingItf_ _3DGrouping_3DGroupingItf = {
3966bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGrouping_Set3DGroup,
3967bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DGrouping_Get3DGroup
3968bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
3969bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3970bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DMacroscopic implementation */
3971bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
3972bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetSize(SL3DMacroscopicItf self,
3973bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter width, SLmillimeter height, SLmillimeter depth)
39742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
39752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3978bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_GetSize(SL3DMacroscopicItf self,
3979bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter *pWidth, SLmillimeter *pHeight, SLmillimeter *pDepth)
39802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
39812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3984bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self,
3985bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
39862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
39872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3990bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self,
3991bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLVec3D *pFront, const SLVec3D *pAbove)
39922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
39932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
39942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
39952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3996bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_Rotate(SL3DMacroscopicItf self,
3997bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree theta, const SLVec3D *pAxis)
39982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
39992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4002bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self,
4003bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLVec3D *pFront, SLVec3D *pUp)
4004bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4005bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4006bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4007bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4008bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DMacroscopicItf_ _3DMacroscopic_3DMacroscopicItf = {
4009bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetSize,
4010bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_GetSize,
4011bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetOrientationAngles,
4012bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_SetOrientationVectors,
4013bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_Rotate,
4014bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DMacroscopic_GetOrientationVectors
40152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
40162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4017bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* 3DSource implementation */
40182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4019bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetHeadRelative(SL3DSourceItf self,
4020bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean headRelative)
40212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4025bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetHeadRelative(SL3DSourceItf self,
4026bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pHeadRelative)
40272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4031bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffDistances(SL3DSourceItf self,
4032bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter minDistance, SLmillimeter maxDistance)
40332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4037bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffDistances(SL3DSourceItf self,
4038bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillimeter *pMinDistance, SLmillimeter *pMaxDistance)
40392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4043bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self,
4044bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean mute)
40452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4049bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self,
4050bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pMute)
40512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4055bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffFactor(SL3DSourceItf self,
4056bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille rolloffFactor)
40572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4061bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffFactor(SL3DSourceItf self,
4062bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pRolloffFactor)
40632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4067bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRoomRolloffFactor(SL3DSourceItf self,
4068bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille roomRolloffFactor)
40692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4073bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRoomRolloffFactor(SL3DSourceItf self,
4074bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pRoomRolloffFactor)
40752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4079bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetRolloffModel(SL3DSourceItf self, SLuint8 model)
4080bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4081bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4082bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
40832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4084bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetRolloffModel(SL3DSourceItf self, SLuint8 *pModel)
40852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4089bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_SetCone(SL3DSourceItf self, SLmillidegree innerAngle,
4090bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree outerAngle, SLmillibel outerLevel)
40912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
40932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
40942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4095bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult _3DSource_GetCone(SL3DSourceItf self,
4096bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillidegree *pInnerAngle, SLmillidegree *pOuterAngle,
4097bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pOuterLevel)
40982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
40992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4102bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SL3DSourceItf_ _3DSource_3DSourceItf = {
4103bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetHeadRelative,
4104bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetHeadRelative,
4105bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffDistances,
4106bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffDistances,
4107bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffMaxDistanceMute,
4108bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffMaxDistanceMute,
4109bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffFactor,
4110bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffFactor,
4111bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRoomRolloffFactor,
4112bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRoomRolloffFactor,
4113bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetRolloffModel,
4114bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetRolloffModel,
4115bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_SetCone,
4116bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    _3DSource_GetCone
41172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
41182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4119bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* Equalizer implementation */
41202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4121bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
41222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4126bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
41272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4131bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetNumberOfBands(SLEqualizerItf self,
4132bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pNumBands)
41332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4137bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandLevelRange(SLEqualizerItf self,
4138bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pMin, SLmillibel *pMax)
41392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4143bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_SetBandLevel(SLEqualizerItf self, SLuint16 band,
4144bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel level)
41452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4149bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandLevel(SLEqualizerItf self, SLuint16 band,
4150bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pLevel)
41512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4155bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band,
4156bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pCenter)
41572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4161bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
4162bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmilliHertz *pMin, SLmilliHertz *pMax)
41632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4167bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency,
4168bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pBand)
41692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4173bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetCurrentPreset(SLEqualizerItf self,
4174bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pPreset)
41752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4179bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_UsePreset(SLEqualizerItf self, SLuint16 index)
41802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4184bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetNumberOfPresets(SLEqualizerItf self,
4185bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pNumPresets)
41862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4190bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Equalizer_GetPresetName(SLEqualizerItf self, SLuint16 index,
4191bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLchar ** ppName)
41922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
41932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
41942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
41952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4196bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEqualizerItf_ Equalizer_EqualizerItf = {
4197bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_SetEnabled,
4198bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_IsEnabled,
4199bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetNumberOfBands,
4200bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandLevelRange,
4201bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_SetBandLevel,
4202bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandLevel,
4203bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetCenterFreq,
4204bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBandFreqRange,
4205bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetBand,
4206bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetCurrentPreset,
4207bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_UsePreset,
4208bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetNumberOfPresets,
4209bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Equalizer_GetPresetName
42102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
42112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4212bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// PresetReverb implementation
42132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4214bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PresetReverb_SetPreset(SLPresetReverbItf self,
4215bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 preset)
42162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4217bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface *this =
4218bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct PresetReverb_interface *) self;
4219bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mPreset = preset;
42202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4223bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult PresetReverb_GetPreset(SLPresetReverbItf self,
4224bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint16 *pPreset)
42252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4226bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pPreset)
4227bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4228bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct PresetReverb_interface *this =
4229bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct PresetReverb_interface *) self;
4230bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pPreset = this->mPreset;
42312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4234bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLPresetReverbItf_ PresetReverb_PresetReverbItf = {
4235bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PresetReverb_SetPreset,
4236bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    PresetReverb_GetPreset
42372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
42382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4239bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// EnvironmentalReverb implementation
42402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4241bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetRoomLevel(SLEnvironmentalReverbItf self,
4242bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel room)
42432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4247bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetRoomLevel(SLEnvironmentalReverbItf self,
4248bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLmillibel *pRoom)
42492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4253bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetRoomHFLevel(
4254bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel roomHF)
42552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4259bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetRoomHFLevel(
4260bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pRoomHF)
42612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4265bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDecayTime(
4266bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond decayTime)
42672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4271bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDecayTime(
4272bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pDecayTime)
42732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4277bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDecayHFRatio(
4278bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille decayHFRatio)
42792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4283bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDecayHFRatio(
4284bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille *pDecayHFRatio)
42852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4289bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReflectionsLevel(
4290bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel reflectionsLevel)
42912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
42942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4295bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReflectionsLevel(
4296bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pReflectionsLevel)
42972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
42982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
42992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4301bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReflectionsDelay(
4302bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond reflectionsDelay)
43032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4307bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReflectionsDelay(
4308bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pReflectionsDelay)
43092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4313bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReverbLevel(
4314bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel reverbLevel)
43152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4319bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReverbLevel(
4320bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillibel *pReverbLevel)
43212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4325bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetReverbDelay(
4326bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond reverbDelay)
4327bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4328bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4329bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
43302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4331bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetReverbDelay(
4332bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLmillisecond *pReverbDelay)
4333bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4334bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4335bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
43362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4337bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDiffusion(
4338bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLpermille diffusion)
43392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4343bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDiffusion(SLEnvironmentalReverbItf self,
4344bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten     SLpermille *pDiffusion)
43452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4349bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetDensity(SLEnvironmentalReverbItf self,
4350bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille density)
43512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4355bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetDensity(SLEnvironmentalReverbItf self,
4356bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pDensity)
43572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4361bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_SetEnvironmentalReverbProperties(
4362bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self,
4363bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    const SLEnvironmentalReverbSettings *pProperties)
43642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4368bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult EnvironmentalReverb_GetEnvironmentalReverbProperties(
4369bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLEnvironmentalReverbItf self, SLEnvironmentalReverbSettings *pProperties)
43702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
43712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
43722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
43732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4374bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLEnvironmentalReverbItf_
4375bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_EnvironmentalReverbItf = {
4376bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetRoomLevel,
4377bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetRoomLevel,
4378bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetRoomHFLevel,
4379bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetRoomHFLevel,
4380bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDecayTime,
4381bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDecayTime,
4382bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDecayHFRatio,
4383bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDecayHFRatio,
4384bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReflectionsLevel,
4385bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReflectionsLevel,
4386bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReflectionsDelay,
4387bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReflectionsDelay,
4388bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReverbLevel,
4389bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReverbLevel,
4390bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetReverbDelay,
4391bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetReverbDelay,
4392bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDiffusion,
4393bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDiffusion,
4394bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetDensity,
4395bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetDensity,
4396bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_SetEnvironmentalReverbProperties,
4397bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    EnvironmentalReverb_GetEnvironmentalReverbProperties
43982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
43992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4400bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Virtualizer implementation
44012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4402bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_SetEnabled(SLVirtualizerItf self, SLboolean enabled)
44032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4404bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4405bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mEnabled = enabled;
44062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4409bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_IsEnabled(SLVirtualizerItf self,
4410bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pEnabled)
44112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4412bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pEnabled)
4413bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4414bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4415bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEnabled = this->mEnabled;
44162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4419bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_SetStrength(SLVirtualizerItf self,
4420bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille strength)
4421bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4422bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4423bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mStrength = strength;
4424bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4425bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4426bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4427bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_GetRoundedStrength(SLVirtualizerItf self,
4428bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLpermille *pStrength)
4429bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4430bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pStrength)
4431bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4432bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct Virtualizer_interface *this = (struct Virtualizer_interface *) self;
4433bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pStrength = this->mStrength;
4434bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4435bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4436bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4437bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic SLresult Virtualizer_IsStrengthSupported(SLVirtualizerItf self,
4438bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean *pSupported)
4439bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten{
4440bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pSupported)
4441bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4442bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pSupported = SL_BOOLEAN_TRUE;
4443bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
4444bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten}
4445bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4446bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLVirtualizerItf_ Virtualizer_VirtualizerItf = {
4447bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_SetEnabled,
4448bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_IsEnabled,
4449bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_SetStrength,
4450bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_GetRoundedStrength,
4451bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    Virtualizer_IsStrengthSupported
44522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
44532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
44542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Initial entry points */
44552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4456bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifndef __cplusplus
4457bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
44582045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
44592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
44602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
44612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
44622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEngine)
44632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4464bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEngine = NULL;
4465bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // default values
4466bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean threadSafe = SL_BOOLEAN_TRUE;
4467bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLboolean lossOfControl = SL_BOOLEAN_FALSE;
4468bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL != pEngineOptions) {
4469bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        SLuint32 i;
4470bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten		const SLEngineOption *option = pEngineOptions;
4471bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        for (i = 0; i < numOptions; ++i, ++option) {
4472bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            switch (option->feature) {
4473bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            case SL_ENGINEOPTION_THREADSAFE:
4474bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                threadSafe = (SLboolean) option->data;
4475bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                break;
4476bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            case SL_ENGINEOPTION_LOSSOFCONTROL:
4477bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                lossOfControl = (SLboolean) option->data;
4478bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                break;
4479bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            default:
4480bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
4481bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            }
4482bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        }
4483bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    }
4484bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    unsigned exposedMask;
4485bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result = checkInterfaces(&Engine_class, numInterfaces,
4486bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        pInterfaceIds, pInterfaceRequired, &exposedMask);
44872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
44882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
44892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Engine_class *this =
4490bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct Engine_class *) construct(&Engine_class, exposedMask);
4491bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == this)
44922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
4493bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mThreadSafe = threadSafe;
4494bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    this->mLossOfControl = lossOfControl;
4495bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pEngine = &this->mObject.mItf;
44962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
44972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
44982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
44992045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(
45002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pNumSupportedInterfaces)
45012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4502bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pNumSupportedInterfaces)
45032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4504bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pNumSupportedInterfaces = Engine_class.mInterfaceCount;
4505bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
45062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
45082045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index,
45092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLInterfaceID *pInterfaceId)
45102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4511bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]) < index)
4512bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4513bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    if (NULL == pInterfaceId)
45142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
4515bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    *pInterfaceId = &SL_IID_array[Engine_interfaces[index].mMPH];
4516bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    return SL_RESULT_SUCCESS;
45172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
45182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4519bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // !__cplusplus
4520bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4521bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#ifdef USE_OUTPUTMIXEXT
4522bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4523bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/* OutputMixExt implementation */
4524bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4525bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// Used by SDL and Android but not specific to or dependent on either platform
45262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4527bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kastenstatic void OutputMixExt_FillBuffer(SLOutputMixExtItf self, void *pBuffer,
4528bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLuint32 size)
45292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
45302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // Force to be a multiple of a frame, assumes stereo 16-bit PCM
45312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    size &= ~3;
4532bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMixExt_interface *thisExt =
4533bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (struct OutputMixExt_interface *) self;
4534bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    struct OutputMix_interface *this =
4535bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        &((struct OutputMix_class *) thisExt->this)->mOutputMix;
45362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned activeMask = this->mActiveMask;
45372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = &this->mTracks[0];
45382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned i;
45392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mixBufferHasData = SL_BOOLEAN_FALSE;
45402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME O(32) loop even when few tracks are active.
45412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // To avoid loop, use activeMask to check for active track(s)
45422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // and decide whether we actually need to copy or mix.
45432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    for (i = 0; 0 != activeMask; ++i, ++track, activeMask >>= 1) {
45442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(i < 32);
45452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (!(activeMask & 1))
45462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
45472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is allocated
45482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct Play_interface *play = track->mPlay;
45492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == play)
45502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
45512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is initialized
45522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_PLAYSTATE_PLAYING != play->mState)
45532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
45542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is playing
45552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        void *dstWriter = pBuffer;
45562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned desired = size;
45572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLboolean trackContributedToMix = SL_BOOLEAN_FALSE;
45582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        while (desired > 0) {
45592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            struct BufferQueue_interface *bufferQueue;
45602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            const struct BufferHeader *oldFront, *newFront, *rear;
45612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            unsigned actual = desired;
45622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (track->mAvail < actual)
45632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                actual = track->mAvail;
45642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // force actual to be a frame multiple
45652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (actual > 0) {
45662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME check for either mute or volume 0
45672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // in which case skip the input buffer processing
45682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                assert(NULL != track->mReader);
45692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME && gain == 1.0
45702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (mixBufferHasData) {
4571bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    stereo *mixBuffer = (stereo *) dstWriter;
4572bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    const stereo *source = (const stereo *) track->mReader;
45732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    unsigned j;
4574bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    for (j = 0; j < actual; j += sizeof(stereo), ++mixBuffer,
4575bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        ++source) {
45762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // apply gain here
45772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->left += source->left;
45782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->right += source->right;
45792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
45802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                } else {
45812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    memcpy(dstWriter, track->mReader, actual);
45822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    trackContributedToMix = SL_BOOLEAN_TRUE;
45832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
45842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                dstWriter = (char *) dstWriter + actual;
45852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                desired -= actual;
45862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mReader = (char *) track->mReader + actual;
45872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mAvail -= actual;
45882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (track->mAvail == 0) {
45892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    bufferQueue = track->mBufferQueue;
45902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (NULL != bufferQueue) {
45912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        oldFront = bufferQueue->mFront;
45922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        rear = bufferQueue->mRear;
45932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(oldFront != rear);
45942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        newFront = oldFront;
4595bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        if (++newFront ==
4596bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                            &bufferQueue->mArray[bufferQueue->mNumBuffers])
45972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                            newFront = bufferQueue->mArray;
45982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        bufferQueue->mFront = (struct BufferHeader *) newFront;
45992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(0 < bufferQueue->mState.count);
46002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        --bufferQueue->mState.count;
46012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // FIXME here or in Enqueue?
46022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        ++bufferQueue->mState.playIndex;
4603bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        // FIXME a good time to do an early warning
46042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // callback depending on buffer count
46052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
46062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
46072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
46082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
46092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // actual == 0
46102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            bufferQueue = track->mBufferQueue;
46112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL != bufferQueue) {
46122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                oldFront = bufferQueue->mFront;
46132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                rear = bufferQueue->mRear;
46142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (oldFront != rear) {
46152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastengot_one:
46162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    assert(0 < bufferQueue->mState.count);
46172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mReader = oldFront->mBuffer;
46182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mAvail = oldFront->mSize;
46192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    continue;
46202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
46212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME should be able to configure when to
46222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // kick off the callback e.g. high/low water-marks etc.
4623bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                // need data but none available, attempt a desperate callback
46242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                slBufferQueueCallback callback = bufferQueue->mCallback;
46252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (NULL != callback) {
4626bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    (*callback)((SLBufferQueueItf) bufferQueue,
4627bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                        bufferQueue->mContext);
4628bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    // if lucky, the callback enqueued a buffer
46292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (rear != bufferQueue->mRear)
46302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        goto got_one;
4631bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten                    // unlucky, queue still empty, the callback failed
46322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
46332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // here on underflow due to no callback, or failed callback
46342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME underflow, send silence (or previous buffer?)
46352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // we did a callback to try to kick start again but failed
46362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // should log this
46372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
4638bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten            // no buffer queue or underflow, clear out rest of partial buffer
46392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!mixBufferHasData && trackContributedToMix)
46402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                memset(dstWriter, 0, actual);
46412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
46422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
46432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (trackContributedToMix)
46442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            mixBufferHasData = SL_BOOLEAN_TRUE;
46452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
46462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // No active tracks, so output silence
46472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!mixBufferHasData)
46482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memset(pBuffer, 0, size);
46492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4651bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten/*static*/ const struct SLOutputMixExtItf_ OutputMixExt_OutputMixExtItf = {
4652bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMixExt_FillBuffer
4653bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten};
4654bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
4655bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_OUTPUTMIXEXT
4656bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
46572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
46582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4659bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten// FIXME move to separate source file
4660bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten
46612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* SDL platform implementation */
46622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
46632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SDLCALL SDL_callback(void *context, Uint8 *stream, int len)
46642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
46652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    assert(len > 0);
4666bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    OutputMixExt_FillBuffer((SLOutputMixExtItf) context, stream,
4667bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten        (SLuint32) len);
46682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
46702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenvoid SDL_start(SLObjectItf self)
46712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
4672bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //assert(self != NULL);
46732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME make this an operation on Object: GetClass
4674bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //struct Object_interface *this = (struct Object_interface *) self;
4675bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    //assert(&OutputMix_class == this->mClass);
4676bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLresult result;
4677bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    SLOutputMixExtItf OutputMixExt;
4678bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    result = (*self)->GetInterface(self, SL_IID_OUTPUTMIXEXT, &OutputMixExt);
4679bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
46802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
46812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_AudioSpec fmt;
46822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.freq = 44100;
46832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.format = AUDIO_S16;
46842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.channels = 2;
46852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.samples = 256;
46862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.callback = SDL_callback;
4687bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // FIXME should be a GetInterface
4688bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    // fmt.userdata = &((struct OutputMix_class *) this)->mOutputMixExt;
4689bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten    fmt.userdata = (void *) OutputMixExt;
46902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
46912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SDL_OpenAudio(&fmt, NULL) < 0) {
46922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
46932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        exit(1);
46942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
46952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_PauseAudio(0);
46962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
46972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4698bd3cb772fc94c5baf0d1fe1a63693b33ca5fe9e3Glenn Kasten#endif // USE_SDL
4699d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
4700d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */
4701