sles.cpp revision d7143537437acbd4b97761a1c5bf852be9ba485a
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
9d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include <stdio.h> // debugging
10d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
11d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Forward declarations */
12d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
13d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLObjectItf_ Object_ObjectItf;
14d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLDynamicInterfaceManagementItf_
15d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_DynamicInterfaceManagementItf;
16d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLEngineItf_ Engine_EngineItf;
17d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLOutputMixItf_ OutputMix_OutputMixItf;
18d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLPlayItf_ Play_PlayItf;
19d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLVolumeItf_ Volume_VolumeItf;
20d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf;
21d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
22d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private types */
23d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
24d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct iid_vtable {
25d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *iid;
26d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    size_t offset;
27d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
28d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
29d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Per-class data shared by all instances of the same class */
30d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
31d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct class {
32d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // needed by all classes (class class, the superclass of all classes)
33d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct iid_vtable *interfaces;
34d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLuint32 interfaceCount;
35d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const char * const name;
36d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const size_t size;
37d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // non-const here and below
38d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 instanceCount;
39d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // append per-class data here
40d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
41d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
42d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Interfaces */
43d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
44d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Object_interface {
45d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLObjectItf_ *itf;
46d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // probably not needed for an Object, as it is always first
47d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
48d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
49d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct class *mClass;
50d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLuint32 mState;
51d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slObjectCallback mCallback;
52d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
53d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME a thread lock would go here
54d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME also an object ID for RPC and human-readable name for debugging
55d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
56d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
57d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct DynamicInterfaceManagement_interface {
58d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLDynamicInterfaceManagementItf_ *itf;
59d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
60d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
61d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
62d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
63d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Engine_interface {
64d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEngineItf_ *itf;
65d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
66d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
67d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
68d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
69d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct OutputMix_interface {
70d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLOutputMixItf_ *itf;
71d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
72d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
73d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
74d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
75d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Play_interface {
76d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLPlayItf_ *itf;
77d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
78d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
79d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLuint32 mState;
80d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
81d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
82d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct BufferQueue_interface {
83d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLBufferQueueItf_ *itf;
84d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
85d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
86d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLBufferQueueState mState;
87d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback mCallback;
88d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
89d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 mNumBuffers;
90d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader {
91d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // circular
92d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // struct Buffer *mNext;
93d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        const void *mBuffer;
94d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        SLuint32 mSize;
95d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    } *mArray, *mFront, *mRear;
96d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
97d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
98d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0 // not yet needed
99d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
100d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct EnvironmentalReverb_interface {
101d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEnvironmentalReverbItf_ *itf;
102d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
103d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
104d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Equalizer_interface {
107d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEqualizerItf_ *itf;
108d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
109d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
110d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
111d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
112d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct PresetReverb_interface {
113d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLPresetReverbItf_ *itf;
114d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
115d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
116d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
117d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
118d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Virtualizer_interface {
119d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLVirtualizerItf_ *itf;
120d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
121d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
122d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
123d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
124d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
125d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
126d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Volume_interface {
127d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLVolumeItf_ *itf;
128d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
129d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
130d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLmillibel mLevel;
131d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
132d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
133d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Classes */
134d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
135d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Engine_class {
136d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
137d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
138d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Engine_interface mEngine;
139d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0
140d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten// more
141d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
142d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields not associated with interfaces goes here
143d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
144d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
145d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct OutputMix_class {
146d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
147d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
148d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct OutputMix_interface mOutputMix;
149d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0
150d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
151d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Equalizer_interface mEqualizer;
152d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct PresetReverb_interface mPresetReverb;
153d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Virtualizer_interface mVirtualizer;
154d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
155d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
156d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
157d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
158d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct AudioPlayer_class {
159d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
160d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
161d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface mPlay;
162d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface mBufferQueue;
163d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
164d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
165d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
166d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private functions */
167d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
168d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult checkInterfaces(const struct iid_vtable *interfaces,
169d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 interfaceCount, SLuint32 numInterfaces,
170d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
171d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
172d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (0 < numInterfaces) {
173d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == pInterfaceIds || NULL == pInterfaceRequired)
174d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
175d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME O(N^2)
176d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        SLuint32 i, j;
177d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        for (i = 0; i < numInterfaces; ++i) {
178d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            for (j = 0; j < interfaceCount; ++j) {
179d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                if (pInterfaceIds[i] == *interfaces[j].iid ||
180d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                !memcmp(pInterfaceIds[i], *interfaces[j].iid, sizeof(struct SLInterfaceID_)))
181d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                    goto found;
182d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
183d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            if (SL_BOOLEAN_FALSE != pInterfaceRequired[i])
184d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_FEATURE_UNSUPPORTED;
185d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenfound:
186d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            ;
187d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
189d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
190d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
191d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
192d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Classes */
193d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
194d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable Engine_interfaces[] = {
195d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct Engine_class, mObject)},
196d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT, offsetof(struct Engine_class, mDynamicInterfaceManagement)},
197d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_ENGINE, offsetof(struct Engine_class, mEngine)}
198d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0
199d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_ENGINECAPABILITIES, NULL},
200d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_THREADSYNC, NULL},
201d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_AUDIOIODEVICECAPABILITIES, NULL},
202d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_AUDIODECODERCAPABILITIES, NULL},
203d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_AUDIOENCODERCAPABILITIES, NULL},
204d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_3DCOMMIT, NULL}
205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // SL_IID_DEVICEVOLUME
206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
207d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
208d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
209d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class Engine_class = {
210d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_interfaces,
211d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]),
212d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "Engine",
213d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    0,
214d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(struct Engine_class)
215d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
216d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
217d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable OutputMix_interfaces[] = {
218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct OutputMix_class, mObject)},
219d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT, offsetof(struct OutputMix_class, mDynamicInterfaceManagement)},
220d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OUTPUTMIX, offsetof(struct OutputMix_class, mOutputMix)},
221d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_VOLUME, offsetof(struct OutputMix_class, mVolume)}
222d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
223d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
224d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class OutputMix_class = {
225d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    OutputMix_interfaces,
226d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(OutputMix_interfaces)/sizeof(OutputMix_interfaces[0]),
227d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "OutputMix",
228d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    0,
229d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(struct OutputMix_class)
230d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
232d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable AudioPlayer_interfaces[] = {
233d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct AudioPlayer_class, mObject)},
234d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT, offsetof(struct AudioPlayer_class, mDynamicInterfaceManagement)},
235d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_PLAY, offsetof(struct AudioPlayer_class, mPlay)},
236d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_BUFFERQUEUE, offsetof(struct AudioPlayer_class, mBufferQueue)},
237d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_VOLUME, offsetof(struct AudioPlayer_class, mVolume)}
238d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
239d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
240d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class AudioPlayer_class = {
241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    AudioPlayer_interfaces,
242d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(AudioPlayer_interfaces)/sizeof(AudioPlayer_interfaces[0]),
243d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "AudioPlayer",
244d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    0,
245d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(struct AudioPlayer_class)
246d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
247d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
248d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Object implementation */
249d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
250d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_Realize(SLObjectItf self, SLboolean async)
251d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
252d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
253d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME locking needed here in case two threads call Realize at once
254d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (this->mState != SL_OBJECT_STATE_UNREALIZED)
255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
256d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_REALIZED;
257d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0 // FIXME
258d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void (*callback)(void) = NULL;
259d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_BOOLEAN_FALSE != async)
260d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        callback();
261d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
262d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
263d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
264d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
265d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_Resume(SLObjectItf self, SLboolean async)
266d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
267d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0 // FIXME
268d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void (*callback)(void) = NULL;
269d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_BOOLEAN_FALSE != async)
270d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        callback();
271d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
272d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
273d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
274d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
275d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_GetState(SLObjectItf self, SLuint32 * pState)
276d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
277d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
278d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
279d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
280d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
281d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
282d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_GetInterface(SLObjectItf self, const SLInterfaceID iid,
285d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void * pInterface)
286d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
287d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    unsigned i;
288d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pInterface)
289d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
290d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
291d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct class *class = this->mClass;
292d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME O(n) - could be O(1) by hashing etc.
293d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    for (i = 0; i < class->interfaceCount; ++i) {
294d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (iid == *class->interfaces[i].iid ||
295d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            !memcmp(iid, *class->interfaces[i].iid, sizeof(struct SLInterfaceID_))) {
296d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            *(void **)pInterface = (char *) this + class->interfaces[i].offset;
297d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_SUCCESS;
298d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
299d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
300d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
301d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
302d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
303d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_RegisterCallback(SLObjectItf self,
304d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slObjectCallback callback, void * pContext)
305d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
306d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
307d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME thread safety
308d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
309d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
310d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
311d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
312d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
313d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic void Object_AbortAsyncOperation(SLObjectItf self)
314d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
315d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
316d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
317d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic void Object_Destroy(SLObjectItf self)
318d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
319d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_AbortAsyncOperation(self);
320d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
321d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_UNREALIZED;
322d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
323d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
324d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_SetPriority(SLObjectItf self, SLint32 priority,
325d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean preemptable)
326d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
327d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
328d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
329d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
330d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_GetPriority(SLObjectItf self, SLint32 *pPriority,
331d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pPreemptable)
332d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
333d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
334d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
335d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
336d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_SetLossOfControlInterfaces(SLObjectItf self,
337d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled)
338d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
339d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
340d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
341d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
342d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLObjectItf_ Object_ObjectItf = {
343d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Realize,
344d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Resume,
345d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetState,
346d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetInterface,
347d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_RegisterCallback,
348d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_AbortAsyncOperation,
349d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Destroy,
350d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_SetPriority,
351d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetPriority,
352d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_SetLossOfControlInterfaces,
353d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
354d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
355d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* DynamicInterfaceManagement implementation */
356d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
357d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_AddInterface(
358d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
359d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
360d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
361d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
362d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
363d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
364d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RemoveInterface(
365d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
366d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid)
367d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
368d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
369d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
370d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
371d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_ResumeInterface(
372d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
373d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
374d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
375d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
376d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
377d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
378d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RegisterCallback(
379d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
380d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slDynamicInterfaceManagementCallback callback, void *pContext)
381d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
382d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
383d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
384d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
385d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLDynamicInterfaceManagementItf_
386d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenDynamicInterfaceManagement_DynamicInterfaceManagementItf = {
387d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_AddInterface,
388d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RemoveInterface,
389d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_ResumeInterface,
390d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RegisterCallback
391d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
392d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
393d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Play implementation */
394d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
395d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPlayState(SLPlayItf self, SLuint32 state)
396d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
397d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (state) {
398d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_STOPPED:
399d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PAUSED:
400d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PLAYING:
401d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
402d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
403d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
404d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
405d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
406d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = state;
407d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
408d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
409d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
410d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPlayState(SLPlayItf self, SLuint32 *pState)
411d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
412d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
413d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
414d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
415d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
416d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
417d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
418d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
419d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetDuration(SLPlayItf self,  SLmillisecond *pMsec)
420d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
421d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
422d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
423d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
424d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPosition(SLPlayItf self,  SLmillisecond *pMsec)
425d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
426d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
427d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
428d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
429d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_RegisterCallback(SLPlayItf self, slPlayCallback callback,
430d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *pContext)
431d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
432d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
433d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
434d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
435d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
436d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
437d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
438d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
439d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
440d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetCallbackEventsMask(SLPlayItf self, SLuint32 *pEventFlags)
441d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
442d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
443d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
444d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
445d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
446d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
447d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
448d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
449d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
450d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_ClearMarkerPosition(SLPlayItf self)
451d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
452d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
453d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
454d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
455d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
456d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
457d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
458d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
459d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
460d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
461d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
462d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
463d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
464d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
465d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPositionUpdatePeriod(SLPlayItf self, SLmillisecond *pMsec)
466d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
467d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
468d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
469d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
470d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLPlayItf_ Play_PlayItf = {
471d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPlayState,
472d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPlayState,
473d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetDuration,
474d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPosition,
475d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_RegisterCallback,
476d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetCallbackEventsMask,
477d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetCallbackEventsMask,
478d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetMarkerPosition,
479d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_ClearMarkerPosition,
480d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetMarkerPosition,
481d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPositionUpdatePeriod,
482d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPositionUpdatePeriod
483d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
484d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
485d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* BufferQueue implementation */
486d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
487d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer,
488d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 size)
489d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
490d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pBuffer)
491d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
492d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
493d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME race condition need mutex
494d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // circular
495d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *oldRear = this->mRear;
496d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *newRear = oldRear;
497d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (++newRear == &this->mArray[this->mNumBuffers])
498d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        newRear = this->mArray;
499d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (newRear == this->mFront)
500d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_BUFFER_INSUFFICIENT;
501d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mBuffer = pBuffer;
502d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mSize = size;
503d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mRear = newRear;
504d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
505d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
506d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
507d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Clear(SLBufferQueueItf self)
508d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
509d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
510d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
511d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
512d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_GetState(SLBufferQueueItf self, SLBufferQueueState *pState)
513d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
514d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
515d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
517d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
518d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
519d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
520d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
521d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_RegisterCallback(SLBufferQueueItf self,
522d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback callback, void *pContext)
523d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
524d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
525d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
526d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
527d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
528d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
529d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
530d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf = {
531d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Enqueue,
532d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Clear,
533d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_GetState,
534d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_RegisterCallback
535d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
536d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
537d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Volume implementation */
538d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
539d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetVolumeLevel(SLVolumeItf self, SLmillibel level)
540d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
541d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // stet despite warning because MIN and MAX might change, and because
542d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // some compilers allow a wider int type to be passed as a parameter
543d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (!(SL_MILLIBEL_MIN <= level && SL_MILLIBEL_MAX >= level))
544d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
545d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
546d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mLevel = level;
547d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
548d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
549d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
550d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
551d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
552d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
553d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
554d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
555d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetMaxVolumeLevel(SLVolumeItf self, SLmillibel *pMaxLevel)
556d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
557d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
558d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
559d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
560d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetMute(SLVolumeItf self, SLboolean mute)
561d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
562d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
563d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
564d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
565d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetMute(SLVolumeItf self, SLboolean *pMute)
566d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
567d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
568d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
569d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
570d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
571d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
572d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
573d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
574d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
575d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_IsEnabledStereoPosition(SLVolumeItf self,
576d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pEnable)
577d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
578d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
579d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
580d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
581d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetStereoPosition(SLVolumeItf self,
582d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille stereoPosition)
583d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
584d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
585d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
586d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
587d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetStereoPosition(SLVolumeItf self,
588d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille *pStereoPosition)
589d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
590d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
591d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
592d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
593d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLVolumeItf_ Volume_VolumeItf = {
594d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetVolumeLevel,
595d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetVolumeLevel,
596d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMaxVolumeLevel,
597d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetMute,
598d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMute,
599d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_EnableStereoPosition,
600d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_IsEnabledStereoPosition,
601d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetStereoPosition,
602d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetStereoPosition
603d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
605d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Engine implementation */
606d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice,
608d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 deviceID, SLuint32 numInterfaces,
609d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID * pInterfaceIds, const SLboolean *pInterfaceRequired)
610d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
611d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
612d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
613d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
614d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateVibraDevice(SLEngineItf self,
615d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces,
616d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
617d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
618d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
619d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
620d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
621d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
622d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
623d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
624d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
625d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pPlayer)
626d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
627d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = NULL;
628d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pAudioSrc || (NULL == (SLuint32 *) pAudioSrc->pLocator))
629d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
630d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numBuffers = 0;
631d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (*(SLuint32 *)pAudioSrc->pLocator) {
632d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
633d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
634d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        numBuffers = ((SLDataLocator_BufferQueue *) pAudioSrc->pLocator)->numBuffers;
635d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (0 == numBuffers)
636d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
637d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == pAudioSrc->pFormat)
638d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
639d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        switch (*(SLuint32 *)pAudioSrc->pFormat) {
640d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_PCM:
641d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            {
642d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            SLDataFormat_PCM *pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
643d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->numChannels) {
644d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 1:
645d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 2:
646d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
647d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
648d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
649d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
650d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->samplesPerSec) {
651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 44100:
652d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
653d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 1 // wrong units for samplesPerSec!
654d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_SAMPLINGRATE_44_1:
655d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
657d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
658d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
659d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
660d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
661d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->bitsPerSample) {
662d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_PCMSAMPLEFORMAT_FIXED_16:
663d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
664d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
665d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
666d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
667d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
668d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->containerSize) {
669d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 16:
670d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
672d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
673d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
674d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
675d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->channelMask) {
676d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // needs work
677d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
678d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
679d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
680d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            switch (pcm->endianness) {
681d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_BYTEORDER_LITTLEENDIAN:
682d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
683d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others esp. big and native (new not in spec)
684d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
685d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
686d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
687d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
688d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            break;
689d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_MIME:
690d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_RESERVED3:
691d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
692d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        default:
693d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
694d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
695d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
696d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
697d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
698d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_ADDRESS:
699d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_IODEVICE:
700d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
701d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED5:
702d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
703d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED8:
704d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
705d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
706d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
707d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
708d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pAudioSnk || (NULL == (SLuint32 *) pAudioSnk->pLocator))
709d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
710d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (*(SLuint32 *)pAudioSnk->pLocator) {
711d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
712d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
713d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        SLObjectItf outputMix = ((SLDataLocator_OutputMix *) pAudioSnk->pLocator)->outputMix;
714d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME make this an operation on Object: GetClass
715d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == outputMix || (&OutputMix_class != ((struct Object_interface *) outputMix)->mClass))
716d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
717d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
718d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
719d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
720d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
721d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_ADDRESS:
722d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_IODEVICE:
723d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED5:
724d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
725d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED8:
726d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
727d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
728d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
729d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
730d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLresult result = checkInterfaces(AudioPlayer_class.interfaces,
731d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        AudioPlayer_class.interfaceCount, numInterfaces, pInterfaceIds,
732d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        pInterfaceRequired);
733d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
734d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
735d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct AudioPlayer_class *this =
736d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (struct AudioPlayer_class *) malloc(sizeof(struct AudioPlayer_class));
737d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == this) {
738d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pPlayer = NULL;
739d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
740d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
741d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.itf = &Object_ObjectItf;
742d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.this = this;
743d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mClass = &AudioPlayer_class;
744d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
745d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mCallback = NULL;
746d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mContext = NULL;
747d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.itf =
748d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
749d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.this = this;
750d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.itf = &Play_PlayItf;
751d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.this = this;
752d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.mState = SL_PLAYSTATE_STOPPED;
753d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.itf = &BufferQueue_BufferQueueItf;
754d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.this = this;
755d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mState.count = 0;
756d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mState.playIndex = 0;
757d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mCallback = NULL;
758d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mContext = NULL;
759d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mNumBuffers = numBuffers;
760d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mArray = malloc((numBuffers + 1) * sizeof(struct BufferHeader));
761d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // assert(this->mBufferQueue.mArray != NULL);
762d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mFront = this->mBufferQueue.mArray;
763d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mRear = this->mBufferQueue.mArray;
764d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.itf = &Volume_VolumeItf;
765d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.this = this;
766d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.mLevel = 0; // FIXME correct ?
767d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = &this->mObject.itf;
768d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
769d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
770d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
771d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioRecorder(SLEngineItf self,
772d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk,
773d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
774d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
775d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
776d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
777d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
778d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
779d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
780d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
781d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
782d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
783d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
784d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
785d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
786d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
787d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
788d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
789d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
790d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
791d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
792d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
793d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
794d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup,
795d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
796d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
797d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
798d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
799d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
800d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
801d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix,
802d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
803d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
804d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
805d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pMix)
806d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
807d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLresult result = checkInterfaces(OutputMix_class.interfaces,
808d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        OutputMix_class.interfaceCount, numInterfaces, pInterfaceIds,
809d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        pInterfaceRequired);
810d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
811d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
812d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct OutputMix_class *this =
813d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (struct OutputMix_class *) malloc(sizeof(struct OutputMix_class));
814d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == this) {
815d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pMix = NULL;
816d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
817d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
818d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.itf = &Object_ObjectItf;
819d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.this = this;
820d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mClass = &OutputMix_class;
821d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
822d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mCallback = NULL;
823d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mContext = NULL;
824d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.itf =
825d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
826d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.this = this;
827d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mOutputMix.itf = &OutputMix_OutputMixItf;
828d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mOutputMix.this = this;
829d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.itf = &Volume_VolumeItf;
830d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.this = this;
831d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pMix = &this->mObject.itf;
832d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
833d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
834d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
835d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMetadataExtractor(SLEngineItf self,
836d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource,
837d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
838d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
839d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
840d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
841d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
842d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
843d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateExtensionObject(SLEngineItf self,
844d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pObject, void *pParameters, SLuint32 objectID,
845d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
846d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
847d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
848d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
849d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
850d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
851d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedInterfaces(SLEngineItf self,
852d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
853d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
854d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
855d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
856d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
857d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic  SLresult Engine_QuerySupportedInterfaces(SLEngineItf self,
858d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
859d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
860d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
861d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
862d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
863d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedExtensions(SLEngineItf self,
864d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 *pNumExtensions)
865d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
866d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
867d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
868d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
869d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QuerySupportedExtension(SLEngineItf self,
870d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
871d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
872d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
873d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
874d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
875d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_IsExtensionSupported(SLEngineItf self,
876d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLchar *pExtensionName, SLboolean *pSupported)
877d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
878d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
879d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
880d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
881d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLEngineItf_ Engine_EngineItf = {
882d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateLEDDevice,
883d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateVibraDevice,
884d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioPlayer,
885d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioRecorder,
886d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMidiPlayer,
887d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateListener,
888d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_Create3DGroup,
889d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateOutputMix,
890d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMetadataExtractor,
891d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateExtensionObject,
892d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedInterfaces,
893d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedInterfaces,
894d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedExtensions,
895d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedExtension,
896d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_IsExtensionSupported
897d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
898d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
899d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Initial entry points */
900d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
901d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
902d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
903d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
904d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
905d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pEngine)
906d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
907d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME why disallow a non-null pointer if num is 0
908d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if ((0 < numOptions) != (NULL != pEngineOptions))
909d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
910d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLresult result = checkInterfaces(Engine_class.interfaces,
911d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        Engine_class.interfaceCount, numInterfaces, pInterfaceIds,
912d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        pInterfaceRequired);
913d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
914d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
915d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Engine_class *this =
916d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (struct Engine_class *) malloc(sizeof(struct Engine_class));
917d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == this) {
918d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pEngine = NULL;
919d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
920d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
921d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.itf = &Object_ObjectItf;
922d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.this = this;
923d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mClass = &Engine_class;
924d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
925d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mCallback = NULL;
926d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mContext = NULL;
927d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.itf =
928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
929d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.this = this;
930d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mEngine.itf = &Engine_EngineItf;
931d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mEngine.this = this;
932d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pEngine = &this->mObject.itf;
933d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
934d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
935d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
936d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(
937d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 *pNumSupportedInterfaces)
938d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
939d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL != pNumSupportedInterfaces) {
940d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pNumSupportedInterfaces = Engine_class.interfaceCount;
941d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_SUCCESS;
942d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    } else
943d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
944d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
945d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
946d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index,
947d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLInterfaceID *pInterfaceId)
948d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
949d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if ((index < sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0])) &&
950d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (NULL != pInterfaceId)) {
951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pInterfaceId = *Engine_interfaces[index].iid;
952d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_SUCCESS;
953d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    } else
954d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
955d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
956d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
957d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 0
958d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* SDL platform implementation */
959d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
960d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#include "/Library/Frameworks/SDL.framework/Versions/A/Headers/SDL_audio.h"
961d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
962d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic void SDL_callback(void *context, void *stream, int len)
963d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
964d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
965d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
966d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    bufferQueue = (BufferQueue *) context;
967d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferHeader *old_front = bufferQueue->mFront;
968d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (bufferQueue->mFront == bufferQueue->mRear) {
969d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // underflow, send silence (or previous buffer?)
970d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        memset(stream, 0, len);
971d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // should do callback to try to kick start again
972d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    } else {
973d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // should check len == oldFront->mSize
974d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        memcpy(stream, oldFront->mBuffer, len);
975d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
976d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL != mBufferQueue)
977d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        ;
978d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
979d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
980d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenvoid SDL_start(SLBufferQueueItf self)
981d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
982d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
983d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
984d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SDL_AudioSpec fmt;
985d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.freq = 44100;
986d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.format = AUDIO_S16;
987d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.channels = 2;
988d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.samples = 2048; // 512;
989d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.callback = SDL_callback;
990d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    fmt.userdata = this;
991d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
992d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SDL_OpenAudio(&fmt, NULL) < 0) {
993d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
994d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        exit(1);
995d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
996d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SDL_PauseAudio(0);
997d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
998d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
999d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1000d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */
1001