sles.cpp revision 2045b02407f6ac0a570faee3157b24317c8a69e0
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
102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <assert.h>
112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <sndfile.h>
142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#include <SDL/SDL_audio.h>
172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
18d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
19d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Forward declarations */
20d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
21d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLObjectItf_ Object_ObjectItf;
22d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLDynamicInterfaceManagementItf_
23d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_DynamicInterfaceManagementItf;
24d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLEngineItf_ Engine_EngineItf;
25d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLOutputMixItf_ OutputMix_OutputMixItf;
26d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLPlayItf_ Play_PlayItf;
27d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLVolumeItf_ Volume_VolumeItf;
28d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf;
292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioIODeviceCapabilitiesItf_
302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLSeekItf_ Seek_SeekItf;
322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLLEDArrayItf_ LEDArray_LEDArrayItf;
332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLVibraItf_ Vibra_VibraItf;
342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DCommitItf_ _3DCommit_3DCommitItf;
352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DDopplerItf_ _3DDoppler_3DDopplerItf;
362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DLocationItf_ _3DLocation_3DLocationItf;
372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioDecoderCapabilitiesItf_
382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_AudioDecoderCapabilitiesItf;
392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioEncoderItf_ AudioEncoder_AudioEncoderItf;
402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioEncoderCapabilitiesItf_
412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_AudioEncoderCapabilitiesItf;
422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf;
432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLDynamicSourceItf_ DynamicSource_DynamicSourceItf;
442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLEffectSendItf_ EffectSend_EffectSendItf;
452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLEngineCapabilitiesItf_
462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_EngineCapabilitiesItf;
472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMetadataExtractionItf_ MetadataExtraction_MetadataExtractionItf;
482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMetadataTraversalItf_ MetadataTraversal_MetadataTraversalItf;
492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMuteSoloItf_ MuteSolo_MuteSoloItf;
502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPitchItf_ Pitch_PitchItf;
512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPlaybackRateItf_ PlaybackRate_PlaybackRateItf;
522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPrefetchStatusItf_ PrefetchStatus_PrefetchStatusItf;
532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLRatePitchItf_ RatePitch_RatePitchItf;
542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLRecordItf_ Record_RecordItf;
552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf;
562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLVisualizationItf_ Visualization_VisualizationItf;
57d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
58d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private types */
59d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
60d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct iid_vtable {
61d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *iid;
62d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    size_t offset;
63d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
64d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Device table (change this when you port!) */
662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HEADSET 1
682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_headset = {
702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "headset",
712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_ATTACHED_WIRED,
722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_USER,
732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HEADSET,
742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_HANDSFREE 2
842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioOutputDescriptor AudioOutputDescriptor_handsfree = {
862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLchar *) "handsfree",
872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVCONNECTION_INTEGRATED,
882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVSCOPE_ENVIRONMENT,
892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_DEVLOCATION_HANDSET,
902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,
912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,
942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,
952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,
962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2
972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_LED 3
1002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define DEVICE_ID_VIBRA 4
1012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
102d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Per-class data shared by all instances of the same class */
103d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
104d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct class {
105d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // needed by all classes (class class, the superclass of all classes)
106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct iid_vtable *interfaces;
107d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLuint32 interfaceCount;
108d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const char * const name;
1092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME not yet used
110d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const size_t size;
111d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // non-const here and below
1122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME not yet used
113d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 instanceCount;
114d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // append per-class data here
115d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
116d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
117d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Interfaces */
118d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
119d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Object_interface {
120d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLObjectItf_ *itf;
121d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // probably not needed for an Object, as it is always first
122d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
123d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
124d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct class *mClass;
125d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLuint32 mState;
126d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slObjectCallback mCallback;
127d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
128d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME a thread lock would go here
129d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME also an object ID for RPC and human-readable name for debugging
130d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
131d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
132d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct DynamicInterfaceManagement_interface {
133d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLDynamicInterfaceManagementItf_ *itf;
134d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
135d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
136d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
137d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
138d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Engine_interface {
139d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEngineItf_ *itf;
140d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
141d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
142d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
143d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
144d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct OutputMix_interface {
145d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLOutputMixItf_ *itf;
146d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
147d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
1482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned mActiveMask;   // 1 bit per active track
1492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track {
1502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        const SLDataFormat_PCM *mDfPcm;
1512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct BufferQueue_interface *mBufferQueue;
1522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct Play_interface *mPlay; // mixer will examine this track if non-NULL
1532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        const void *mReader;    // pointer to next frame in BufferHeader.mBuffer
1542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 mAvail;        // number of available bytes
1552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    } mTracks[32];
156d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
157d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
158d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Play_interface {
159d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLPlayItf_ *itf;
160d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
161d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
162d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLuint32 mState;
1632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond mDuration;
1642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond mPosition;
1652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // unsigned mPositionSamples;  // position in sample units
166d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
167d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
168d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct BufferQueue_interface {
169d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLBufferQueueItf_ *itf;
170d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
171d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
172d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    volatile SLBufferQueueState mState;
173d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback mCallback;
174d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *mContext;
175d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 mNumBuffers;
1762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // circular
177d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader {
178d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        const void *mBuffer;
179d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        SLuint32 mSize;
180d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    } *mArray, *mFront, *mRear;
1812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME inline alloc of mArray
182d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
183d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
184d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct EnvironmentalReverb_interface {
185d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEnvironmentalReverbItf_ *itf;
186d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
187d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
188d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
189d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
190d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Equalizer_interface {
191d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLEqualizerItf_ *itf;
192d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
193d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
194d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
195d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
196d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct PresetReverb_interface {
197d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLPresetReverbItf_ *itf;
198d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
199d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
200d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
201d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
202d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Virtualizer_interface {
203d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLVirtualizerItf_ *itf;
204d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
207d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct ThreadSync_interface {
2092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLThreadSyncItf_ *itf;
2102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
213d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
214d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Volume_interface {
215d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const struct SLVolumeItf_ *itf;
216d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *this;
217d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields
218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLmillibel mLevel;
2192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mMute;
2202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mEnableStereoPosition;
2212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille mStereoPosition;
2222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioIODeviceCapabilities_interface {
2252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLAudioIODeviceCapabilitiesItf_ *itf;
2262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Seek_interface {
2312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLSeekItf_ *itf;
2322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond mPos;
2352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mLoopEnabled;
2362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond mStartPos;
2372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond mEndPos;
2382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct _3DCommit_interface {
2412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SL3DCommitItf_ *itf;
2422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct EngineCapabilities_interface {
2472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLEngineCapabilitiesItf_ *itf;
2482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioDecoderCapabilities_interface {
2532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLAudioDecoderCapabilitiesItf_ *itf;
2542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioEncoderCapabilities_interface {
2592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLAudioEncoderCapabilitiesItf_ *itf;
2602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct DeviceVolume_interface {
2652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLDeviceVolumeItf_ *itf;
2662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct LEDArray_interface {
2712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLLEDArrayItf_ *itf;
2722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Vibra_interface {
2772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLVibraItf_ *itf;
2782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct PrefetchStatus_interface {
2832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLPrefetchStatusItf_ *itf;
2842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct RatePitch_interface {
2892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLRatePitchItf_ *itf;
2902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct EffectSend_interface {
2952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLEffectSendItf_ *itf;
2962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
2972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
2982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
2992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MuteSolo_interface {
3012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLMuteSoloItf_ *itf;
3022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MetaDataExtraction_interface {
3072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLMetaDataExractionItf_ *itf;
3082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MetaDataTraversal_interface {
3132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLMetaDataTraversalItf_ *itf;
3142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Record_interface {
3192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLRecordItf_ *itf;
3202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioEncoder_interface {
3252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLAudioEncoderItf_ *itf;
3262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct _3DDoppler_interface {
3312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SL3DDopplerItf_ *itf;
3322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct _3DLocation_interface {
3372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SL3DLocationItf_ *itf;
3382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
3402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct DynamicSource_interface {
3432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const struct SLDynamicSourceItf_ *itf;
3442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *this;
3452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // additional fields
346d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
347d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
348d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Classes */
349d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
350d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct Engine_class {
351d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
352d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
353d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Engine_interface mEngine;
3542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct EngineCapabilities_interface mEngineCapabilities;
3552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct ThreadSync_interface mThreadSync;
3562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioIODeviceCapabilities_interface mAudioIODeviceCapabilities;
3572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioDecoderCapabilities_interface mAudioDecoderCapabilities;
3582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioEncoderCapabilities_interface mAudioEncoderCapabilities;
3592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DCommit_interface m3DCommit;
3602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DeviceVolume_interface mDeviceVolume;
361d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // additional fields not associated with interfaces goes here
362d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
363d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
364d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct OutputMix_class {
365d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
366d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
367d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct OutputMix_interface mOutputMix;
368d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct EnvironmentalReverb_interface mEnvironmentalReverb;
369d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Equalizer_interface mEqualizer;
370d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct PresetReverb_interface mPresetReverb;
371d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Virtualizer_interface mVirtualizer;
372d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
373d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
374d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
3752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct LEDDevice_class {
3762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
3772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
3782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct LEDArray_interface mLED;
3792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    //
3802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mDeviceID;
3812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
3832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct VibraDevice_class {
3842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
3852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
3862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Vibra_interface mVibra;
3872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    //
3882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mDeviceID;
3892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
3902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
391d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstruct AudioPlayer_class {
392d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface mObject;
393d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
394d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface mPlay;
3952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // 3D interfaces
396d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface mBufferQueue;
3972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct EffectSend_interface mEffectSend;
3982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MuteSolo_interface mMuteSolo;
3992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
4002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
4012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct PrefetchStatus_interface mPrefetchStatus;
4022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct RatePitch_interface mRatePitch;
4032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
4042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface mVolume;
4052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // optional interfaces
4062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // rest of fields are not related to the interfaces
4072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
4082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct SndFile {
4092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // save URI also?
4102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLchar *mPathname;
4112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SNDFILE *mSNDFILE;
4122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // These are used when Enqueue returns SL_RESULT_BUFFER_INSUFFICIENT
4132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        const void *mRetryBuffer;
4142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 mRetrySize;
4152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLboolean mIs0; // which buffer to use next
4162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME magic numbers
4172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        short mBuffer0[512];
4182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        short mBuffer1[512];
4192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    } mSndFile;
4202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
4212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct AudioRecorder_class {
4242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
4252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
4262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Record_interface mRecord;
4272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioEncoder_interface mAudioEncoder;
4282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // optional
429d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface mVolume;
430d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
431d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
4322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct Listener_class {
4332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
4342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
4352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DDoppler_interface m3DDoppler;
4362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct _3DLocation_interface m3DLocation;
4372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MetadataExtractor_class {
4402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
4412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
4422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicSource_interface mDynamicSource;
4432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataExtraction_interface mMetaDataExtraction;
4442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MetaDataTraversal_interface mMetaDataTraversal;
4452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
4472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstruct MidiPlayer_class {
4482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Object_interface mObject;
4492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct DynamicInterfaceManagement_interface mDynamicInterfaceManagement;
4502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface mPlay;
4512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface mVolume;
4522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface mSeek;
4532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
4542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
455d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Private functions */
456d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
457d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult checkInterfaces(const struct iid_vtable *interfaces,
458d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 interfaceCount, SLuint32 numInterfaces,
459d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
460d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
461d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (0 < numInterfaces) {
462d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (NULL == pInterfaceIds || NULL == pInterfaceRequired)
463d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
464d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME O(N^2)
465d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        SLuint32 i, j;
466d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        for (i = 0; i < numInterfaces; ++i) {
467d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            for (j = 0; j < interfaceCount; ++j) {
468d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                if (pInterfaceIds[i] == *interfaces[j].iid ||
4692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                !memcmp(pInterfaceIds[i], *interfaces[j].iid,
4702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                sizeof(struct SLInterfaceID_)))
471d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                    goto found;
472d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
4732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (pInterfaceRequired[i])
474d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_FEATURE_UNSUPPORTED;
475d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenfound:
476d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            ;
477d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
478d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
479d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
480d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
481d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
482d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Classes */
483d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
484d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable Engine_interfaces[] = {
485d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct Engine_class, mObject)},
4862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
4872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct Engine_class, mDynamicInterfaceManagement)},
4882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_ENGINE, offsetof(struct Engine_class, mEngine)},
4892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_ENGINECAPABILITIES, offsetof(struct Engine_class, mEngineCapabilities)},
4902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_THREADSYNC, offsetof(struct Engine_class, mThreadSync)},
4912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_AUDIOIODEVICECAPABILITIES,
4922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct Engine_class, mAudioIODeviceCapabilities)},
4932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_AUDIODECODERCAPABILITIES,
4942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct Engine_class, mAudioDecoderCapabilities)},
4952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_AUDIOENCODERCAPABILITIES,
4962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct Engine_class, mAudioEncoderCapabilities)},
4972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_3DCOMMIT, offsetof(struct Engine_class, m3DCommit)},
4982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DEVICEVOLUME, offsetof(struct Engine_class, mDeviceVolume)}
499d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
500d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
501d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class Engine_class = {
502d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_interfaces,
503d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0]),
504d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "Engine",
505342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    sizeof(struct Engine_class),
506342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    0
507d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
508d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
509d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable OutputMix_interfaces[] = {
510d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct OutputMix_class, mObject)},
5112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
5122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct OutputMix_class, mDynamicInterfaceManagement)},
513d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OUTPUTMIX, offsetof(struct OutputMix_class, mOutputMix)},
514d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_VOLUME, offsetof(struct OutputMix_class, mVolume)}
515d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
517d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class OutputMix_class = {
518d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    OutputMix_interfaces,
519d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(OutputMix_interfaces)/sizeof(OutputMix_interfaces[0]),
520d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "OutputMix",
521342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    sizeof(struct OutputMix_class),
522342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    0
523d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
524d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
525d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct iid_vtable AudioPlayer_interfaces[] = {
526d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_OBJECT, offsetof(struct AudioPlayer_class, mObject)},
5272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
5282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct AudioPlayer_class, mDynamicInterfaceManagement)},
529d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_PLAY, offsetof(struct AudioPlayer_class, mPlay)},
530d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    {&SL_IID_BUFFERQUEUE, offsetof(struct AudioPlayer_class, mBufferQueue)},
5312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_VOLUME, offsetof(struct AudioPlayer_class, mVolume)},
5322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_SEEK, offsetof(struct AudioPlayer_class, mSeek)}
533d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
534d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
535d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic struct class AudioPlayer_class = {
536d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    AudioPlayer_interfaces,
537d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    sizeof(AudioPlayer_interfaces)/sizeof(AudioPlayer_interfaces[0]),
538d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    "AudioPlayer",
539342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    sizeof(struct AudioPlayer_class),
540342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten    0
541d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
542d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
5432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct iid_vtable LEDDevice_interfaces[] = {
5442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_OBJECT, offsetof(struct LEDDevice_class, mObject)},
5452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
5462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct LEDDevice_class, mDynamicInterfaceManagement)},
5472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_LED, offsetof(struct LEDDevice_class, mLED)},
5482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic struct class LEDDevice_class = {
5512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    LEDDevice_interfaces,
5522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(LEDDevice_interfaces)/sizeof(LEDDevice_interfaces[0]),
5532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    "LEDDevice",
5542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(struct LEDDevice_class),
5552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0
5562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct iid_vtable VibraDevice_interfaces[] = {
5592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_OBJECT, offsetof(struct VibraDevice_class, mObject)},
5602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
5612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct VibraDevice_class, mDynamicInterfaceManagement)},
5622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_VIBRA, offsetof(struct VibraDevice_class, mVibra)},
5632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic struct class VibraDevice_class = {
5662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    VibraDevice_interfaces,
5672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(VibraDevice_interfaces)/sizeof(VibraDevice_interfaces[0]),
5682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    "VibraDevice",
5692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(struct VibraDevice_class),
5702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0
5712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct iid_vtable MidiPlayer_interfaces[] = {
5742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_OBJECT, offsetof(struct MidiPlayer_class, mObject)},
5752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_DYNAMICINTERFACEMANAGEMENT,
5762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        offsetof(struct MidiPlayer_class, mDynamicInterfaceManagement)},
5772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_PLAY, offsetof(struct MidiPlayer_class, mPlay)},
5782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_VOLUME, offsetof(struct MidiPlayer_class, mVolume)},
5792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {&SL_IID_SEEK, offsetof(struct MidiPlayer_class, mSeek)}
5802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic struct class MidiPlayer_class = {
5832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MidiPlayer_interfaces,
5842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(MidiPlayer_interfaces)/sizeof(MidiPlayer_interfaces[0]),
5852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    "MidiPlayer",
5862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(struct MidiPlayer_class),
5872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0
5882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
5892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
5902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Object implementation (generic) */
591d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
592d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_Realize(SLObjectItf self, SLboolean async)
593d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
594d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
595d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME locking needed here in case two threads call Realize at once
5962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_OBJECT_STATE_UNREALIZED != this->mState)
597d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
5982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
599d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_REALIZED;
6002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (async && NULL != this->mCallback)
6012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (*this->mCallback)(self, this->mContext,
6022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mState, NULL);
6032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return result;
604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
605d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
606d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_Resume(SLObjectItf self, SLboolean async)
607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
6082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME process async callback
609d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
610d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
611d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
6122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Object_GetState(SLObjectItf self, SLuint32 *pState)
613d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
614d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
615d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
616d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
617d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
618d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
619d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
620d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
621d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_GetInterface(SLObjectItf self, const SLInterfaceID iid,
6222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    void *pInterface)
623d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
624d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    unsigned i;
625d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pInterface)
626d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
627d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
628d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct class *class = this->mClass;
629d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME O(n) - could be O(1) by hashing etc.
630d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    for (i = 0; i < class->interfaceCount; ++i) {
631d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (iid == *class->interfaces[i].iid ||
6322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            !memcmp(iid, *class->interfaces[i].iid,
6332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            sizeof(struct SLInterfaceID_))) {
634342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten// FIXME code review on 2010/04/16
635342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten// I think it is "this->this" instead of "this" at line 296 :
636342d6fbb17907386701ae5fd4af7a12ca40e87ccGlenn Kasten// *(void **)pInterface = (char *) this + class->interfaces[i].offset;
637d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            *(void **)pInterface = (char *) this + class->interfaces[i].offset;
638d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_SUCCESS;
639d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
640d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
641d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_FEATURE_UNSUPPORTED;
642d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
643d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
644d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_RegisterCallback(SLObjectItf self,
6452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slObjectCallback callback, void *pContext)
646d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
647d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
648d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME thread safety
649d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
650d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
651d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
652d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
653d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
654d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic void Object_AbortAsyncOperation(SLObjectItf self)
655d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
656d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
657d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
658d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic void Object_Destroy(SLObjectItf self)
659d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
660d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_AbortAsyncOperation(self);
661d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Object_interface *this = (struct Object_interface *) self;
662d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = SL_OBJECT_STATE_UNREALIZED;
6632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    free(this);
664d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
665d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
666d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_SetPriority(SLObjectItf self, SLint32 priority,
667d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean preemptable)
668d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
669d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
670d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
672d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_GetPriority(SLObjectItf self, SLint32 *pPriority,
673d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pPreemptable)
674d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
675d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
676d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
677d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
678d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Object_SetLossOfControlInterfaces(SLObjectItf self,
679d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled)
680d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
681d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
682d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
683d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
684d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLObjectItf_ Object_ObjectItf = {
685d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Realize,
686d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Resume,
687d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetState,
688d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetInterface,
689d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_RegisterCallback,
690d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_AbortAsyncOperation,
691d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_Destroy,
692d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_SetPriority,
693d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_GetPriority,
694d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Object_SetLossOfControlInterfaces,
695d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
696d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
6972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioPlayer's implementation of Object interface */
6982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
6992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
7002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
7012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread
7022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext)
7032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
7042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct SndFile *this = (struct SndFile *) pContext;
7052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result;
7062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) {
7072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        result = (*caller)->Enqueue(caller, this->mRetryBuffer, this->mRetrySize);
7082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result)
7092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;     // what, again?
7102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
7112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetryBuffer = NULL;
7122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mRetrySize = 0;
7132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return;
7142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1;
7162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mIs0 ^= SL_BOOLEAN_TRUE;
7172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sf_count_t count;
7182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME magic number
7192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512);
7202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (0 < count) {
7212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 size = count * sizeof(short);
7222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME if we had an internal API, could call this directly
7232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        result = (*caller)->Enqueue(caller, pBuffer, size);
7242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result) {
7252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetryBuffer = pBuffer;
7262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mRetrySize = size;
7272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return;
7282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
7292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
7302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
7322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
7332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLboolean SndFile_IsSupported(const SF_INFO *sfinfo)
7342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
7352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_TYPEMASK) {
7362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_WAV:
7372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
7382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
7392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
7402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->format & SF_FORMAT_SUBMASK) {
7422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SF_FORMAT_PCM_16:
7432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
7442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
7452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
7462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->samplerate) {
7482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 44100:
7492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
7502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
7512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
7522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (sfinfo->channels) {
7542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case 2:
7552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
7562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
7572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_BOOLEAN_FALSE;
7582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_BOOLEAN_TRUE;
7602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
7612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
7622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
7632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
7642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioPlayer_Realize(SLObjectItf self, SLboolean async)
7652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
7662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
7672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME locking needed here in case two threads call Realize at once
7682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_OBJECT_STATE_UNREALIZED != this->mObject.mState)
7692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PRECONDITIONS_VIOLATED;
7702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = SL_RESULT_SUCCESS;
7712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
7722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mPathname) {
7732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SF_INFO sfinfo;
7742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sfinfo.format = 0;
7752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = sf_open(
7762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (const char *) this->mSndFile.mPathname, SFM_READ, &sfinfo);
7772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == this->mSndFile.mSNDFILE) {
7782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_NOT_FOUND;
7792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else if (!SndFile_IsSupported(&sfinfo)) {
7802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            sf_close(this->mSndFile.mSNDFILE);
7812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            this->mSndFile.mSNDFILE = NULL;
7822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = SL_RESULT_CONTENT_UNSUPPORTED;
7832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        } else {
7842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLBufferQueueItf bufferQueue = &this->mBufferQueue.itf;
7852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME should use a private internal API, and disallow
7862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // application to have access to our buffer queue
7872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME if we had an internal API, could call this directly
7882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            result = (*bufferQueue)->RegisterCallback(bufferQueue, SndFile_Callback, &this->mSndFile);
7892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
7902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
7912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
7922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS == result)
7932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mObject.mState = SL_OBJECT_STATE_REALIZED;
7942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (async && NULL != this->mObject.mCallback)
7952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (*this->mObject.mCallback)(self, this->mObject.mContext,
7962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SL_OBJECT_EVENT_ASYNC_TERMINATION, result, this->mObject.mState,
7972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            NULL);
7982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return result;
7992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
8002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
8012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void AudioPlayer_Destroy(SLObjectItf self)
8022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
8032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_AbortAsyncOperation(self);
8042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct AudioPlayer_class *this = (struct AudioPlayer_class *) self;
8052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME stop the player in a way that app can't restart it
8062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mBufferQueue.mArray)
8072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        free(this->mBufferQueue.mArray);
8082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
8092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != this->mSndFile.mSNDFILE) {
8102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        sf_close(this->mSndFile.mSNDFILE);
8112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mSndFile.mSNDFILE = NULL;
8122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
8132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
8142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
8152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    free(this);
8162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
8172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
8182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLObjectItf_ AudioPlayer_ObjectItf = {
8192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioPlayer_Realize,
8202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_Resume,
8212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetState,
8222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetInterface,
8232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_RegisterCallback,
8242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_AbortAsyncOperation,
8252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioPlayer_Destroy,
8262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetPriority,
8272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_GetPriority,
8282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Object_SetLossOfControlInterfaces,
8292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
8302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
831d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* DynamicInterfaceManagement implementation */
832d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
833d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_AddInterface(
834d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
835d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
836d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
837d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
838d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
839d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
840d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RemoveInterface(
841d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
842d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid)
843d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
844d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
845d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
846d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
847d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_ResumeInterface(
848d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
849d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID iid, SLboolean async)
850d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
851d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
852d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
853d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
854d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult DynamicInterfaceManagement_RegisterCallback(
855d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDynamicInterfaceManagementItf self,
856d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slDynamicInterfaceManagementCallback callback, void *pContext)
857d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
858d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
859d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
860d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
861d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLDynamicInterfaceManagementItf_
862d7143537437acbd4b97761a1c5bf852be9ba485aGlenn KastenDynamicInterfaceManagement_DynamicInterfaceManagementItf = {
863d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_AddInterface,
864d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RemoveInterface,
865d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_ResumeInterface,
866d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    DynamicInterfaceManagement_RegisterCallback
867d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
868d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
869d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Play implementation */
870d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
871d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPlayState(SLPlayItf self, SLuint32 state)
872d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
873d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (state) {
874d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_STOPPED:
875d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PAUSED:
876d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_PLAYSTATE_PLAYING:
877d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
878d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
879d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
880d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
881d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
882d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mState = state;
8832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_PLAYSTATE_STOPPED == state) {
8842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        this->mPosition = (SLmillisecond) 0;
8852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // this->mPositionSamples = 0;
8862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
887d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
888d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
889d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
890d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetPlayState(SLPlayItf self, SLuint32 *pState)
891d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
892d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
893d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
894d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
895d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
896d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
897d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
898d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
8992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
900d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
9012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME: for SNDFILE only, check to see if already know duration
9022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // if so, good, otherwise save position,
9032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // read quickly to end of file, counting frames,
9042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // use sample rate to compute duration, then seek back to current position
9052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
9062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
9072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
9082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMsec = this->mDuration;
909d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
910d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
911d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
9122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
913d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
9142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMsec)
9152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
9162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Play_interface *this = (struct Play_interface *) self;
9172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMsec = this->mPosition;
9182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME conver sample units to time units
9192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // SL_TIME_UNKNOWN == this->mPlay.mPosition = SL_TIME_UNKNOWN;
920d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
921d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
922d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
923d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_RegisterCallback(SLPlayItf self, slPlayCallback callback,
924d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    void *pContext)
925d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
926d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
927d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
928d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
929d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
930d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
931d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
932d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
933d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
9342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetCallbackEventsMask(SLPlayItf self,
9352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pEventFlags)
936d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
937d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
938d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
939d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
940d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
941d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
942d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
943d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
944d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
945d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_ClearMarkerPosition(SLPlayItf self)
946d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
947d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
948d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
949d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
950d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
952d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
953d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
954d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
955d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Play_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
956d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
957d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
958d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
959d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
9602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Play_GetPositionUpdatePeriod(SLPlayItf self,
9612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pMsec)
962d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
963d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
964d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
965d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
966d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLPlayItf_ Play_PlayItf = {
967d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPlayState,
968d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPlayState,
969d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetDuration,
970d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPosition,
971d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_RegisterCallback,
972d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetCallbackEventsMask,
973d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetCallbackEventsMask,
974d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetMarkerPosition,
975d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_ClearMarkerPosition,
976d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetMarkerPosition,
977d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_SetPositionUpdatePeriod,
978d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Play_GetPositionUpdatePeriod
979d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
980d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
981d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* BufferQueue implementation */
982d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
983d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer,
984d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 size)
985d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
986d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pBuffer)
987d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
988d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
989d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // FIXME race condition need mutex
990d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *oldRear = this->mRear;
991d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferHeader *newRear = oldRear;
992d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (++newRear == &this->mArray[this->mNumBuffers])
993d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        newRear = this->mArray;
994d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (newRear == this->mFront)
995d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_BUFFER_INSUFFICIENT;
996d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mBuffer = pBuffer;
997d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    oldRear->mSize = size;
998d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mRear = newRear;
9992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ++this->mState.count;
1000d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1001d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1002d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1003d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_Clear(SLBufferQueueItf self)
1004d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
1006d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1007d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1008d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
10092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult BufferQueue_GetState(SLBufferQueueItf self,
10102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLBufferQueueState *pState)
1011d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1012d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pState)
1013d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1014d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
1015d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pState = this->mState;
1016d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1017d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1018d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1019d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult BufferQueue_RegisterCallback(SLBufferQueueItf self,
1020d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    slBufferQueueCallback callback, void *pContext)
1021d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1022d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct BufferQueue_interface *this = (struct BufferQueue_interface *) self;
1023d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mCallback = callback;
1024d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mContext = pContext;
1025d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1026d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1027d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1028d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLBufferQueueItf_ BufferQueue_BufferQueueItf = {
1029d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Enqueue,
1030d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_Clear,
1031d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_GetState,
1032d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    BufferQueue_RegisterCallback
1033d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1034d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1035d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Volume implementation */
1036d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1037d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetVolumeLevel(SLVolumeItf self, SLmillibel level)
1038d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1039d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // stet despite warning because MIN and MAX might change, and because
1040d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // some compilers allow a wider int type to be passed as a parameter
10412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((SL_MILLIBEL_MIN <= level) && (SL_MILLIBEL_MAX >= level)))
1042d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1043d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
1044d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mLevel = level;
1045d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1046d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1047d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1048d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
1049d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLevel)
10512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
10522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
10532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pLevel = this->mLevel;
1054d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1055d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1056d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
10572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Volume_GetMaxVolumeLevel(SLVolumeItf self,
10582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pMaxLevel)
1059d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMaxLevel)
10612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
10622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMaxLevel = SL_MILLIBEL_MAX;
1063d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1064d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1065d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1066d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetMute(SLVolumeItf self, SLboolean mute)
1067d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
10692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mMute = mute;
1070d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1071d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1072d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1073d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetMute(SLVolumeItf self, SLboolean *pMute)
1074d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMute)
10762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
10772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
10782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMute = this->mMute;
1079d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1080d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1081d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1082d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
1083d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
10852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEnableStereoPosition = enable;
1086d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1087d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1088d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1089d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_IsEnabledStereoPosition(SLVolumeItf self,
1090d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLboolean *pEnable)
1091d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
10922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEnable)
10932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
10942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
10952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEnable = this->mEnableStereoPosition;
1096d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1097d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1098d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1099d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_SetStereoPosition(SLVolumeItf self,
1100d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille stereoPosition)
1101d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
11022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
11032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition)))
11042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
11052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStereoPosition = stereoPosition;
1106d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1107d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1108d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1109d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Volume_GetStereoPosition(SLVolumeItf self,
1110d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLpermille *pStereoPosition)
1111d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
11122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pStereoPosition)
11132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
11142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Volume_interface *this = (struct Volume_interface *) self;
11152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStereoPosition = this->mStereoPosition;
1116d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1117d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1118d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1119d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLVolumeItf_ Volume_VolumeItf = {
1120d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetVolumeLevel,
1121d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetVolumeLevel,
1122d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMaxVolumeLevel,
1123d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetMute,
1124d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetMute,
1125d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_EnableStereoPosition,
1126d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_IsEnabledStereoPosition,
1127d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_SetStereoPosition,
1128d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Volume_GetStereoPosition
1129d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1130d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1131d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* Engine implementation */
1132d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1133d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice,
1134d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 deviceID, SLuint32 numInterfaces,
11352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1136d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
11372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDevice)
11382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
11392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
11402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = checkInterfaces(LEDDevice_class.interfaces,
11412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        LEDDevice_class.interfaceCount, numInterfaces, pInterfaceIds,
11422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pInterfaceRequired);
11432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
11442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
11452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct LEDDevice_class *this =
11462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (struct LEDDevice_class *) malloc(sizeof(struct LEDDevice_class));
11472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
11482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
11492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.itf = &Object_ObjectItf;
11502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.this = this;
11512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mClass = &LEDDevice_class;
11522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
11532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mCallback = NULL;
11542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mContext = NULL;
11552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.itf =
11562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
11572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.this = this;
11582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mLED.itf = &LEDArray_LEDArrayItf;
11592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mLED.this = this;
11602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME wrong, and check deviceID vs. DEVICE_ID_LED
11612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
11622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new LED device object
11632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = &this->mObject.itf;
1164d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1165d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1166d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1167d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateVibraDevice(SLEngineItf self,
1168d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pDevice, SLuint32 deviceID, SLuint32 numInterfaces,
1169d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1170d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
11712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDevice)
11722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
11732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = NULL;
11742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = checkInterfaces(VibraDevice_class.interfaces,
11752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        VibraDevice_class.interfaceCount, numInterfaces, pInterfaceIds,
11762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pInterfaceRequired);
11772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
11782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
11792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct VibraDevice_class *this =
11802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (struct VibraDevice_class *) malloc(sizeof(struct VibraDevice_class));
11812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
11822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
11832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.itf = &Object_ObjectItf;
11842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.this = this;
11852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mClass = &VibraDevice_class;
11862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
11872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mCallback = NULL;
11882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mContext = NULL;
11892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.itf =
11902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
11912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.this = this;
11922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVibra.itf = &Vibra_VibraItf;
11932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVibra.this = this;
11942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME wrong, and check deviceID vs. DEVICE_ID_VIBRA
11952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDeviceID = deviceID;
11962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new vibra device object
11972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pDevice = &this->mObject.itf;
1198d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1199d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1200d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1201d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
1202d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
1203d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1204d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1205d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pPlayer)
1206d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1207d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = NULL;
12082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = checkInterfaces(AudioPlayer_class.interfaces,
12092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        AudioPlayer_class.interfaceCount, numInterfaces, pInterfaceIds,
12102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pInterfaceRequired);
12112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
12122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
12132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if ((NULL == pAudioSrc) || (NULL == (SLuint32 *) pAudioSrc->pLocator) ||
12142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (NULL == pAudioSrc->pFormat))
1215d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
12162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
12172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
1218d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numBuffers = 0;
12192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataFormat_PCM *df_pcm = NULL;
12202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = NULL;
12212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
12222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLchar *pathname = NULL;
12232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
12242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (locatorType) {
1225d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
1226d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
12272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_BufferQueue *dl_bq =
12282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
12292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = dl_bq->numBuffers;
1230d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        if (0 == numBuffers)
1231d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
12322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
1233d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_PCM:
1234d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            {
12352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
12362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->numChannels) {
1237d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 1:
1238d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 2:
1239d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1240d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1241d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
1242d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
12432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->samplesPerSec) {
1244d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 44100:
1245d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1246d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#if 1 // wrong units for samplesPerSec!
1247d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_SAMPLINGRATE_44_1:
1248d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1249d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
1250d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
1251d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1252d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
1253d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
12542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->bitsPerSample) {
1255d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_PCMSAMPLEFORMAT_FIXED_16:
1256d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1257d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
1258d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1259d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
1260d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
12612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->containerSize) {
1262d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case 16:
1263d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1264d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others
1265d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1266d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
1267d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
12682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->channelMask) {
1269d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // needs work
1270d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1271d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1272d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
12732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (df_pcm->endianness) {
1274d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            case SL_BYTEORDER_LITTLEENDIAN:
1275d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                break;
1276d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            // others esp. big and native (new not in spec)
1277d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            default:
1278d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
1279d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
1280d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            }
1281d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            break;
1282d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_MIME:
1283d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        case SL_DATAFORMAT_RESERVED3:
1284d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
1285d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        default:
1286d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
1287d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
1288d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
1289d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
12902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
1291d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
12922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        {
12932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
12942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLchar *uri = dl_uri->URI;
12952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == uri)
12962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_PARAMETER_INVALID;
12972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (strncmp((const char *) uri, "file:///", 8))
12982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
12992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pathname = &uri[8];
13002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        switch (formatType) {
13012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        case SL_DATAFORMAT_MIME:
13022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            {
13032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLDataFormat_MIME *df_mime =
13042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                (SLDataFormat_MIME *) pAudioSrc->pFormat;
13052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLchar *mimeType = df_mime->mimeType;
13062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL == mimeType)
13072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_PARAMETER_INVALID;
13082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            SLuint32 containerType = df_mime->containerType;
13092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!strcmp((const char *) mimeType, "audio/x-wav"))
13102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                ;
13112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // else if (others)
13122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            //    ;
13132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            else
13142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
13152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            switch (containerType) {
13162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            case SL_CONTAINERTYPE_WAV:
13172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                break;
13182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // others
13192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            default:
13202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
13212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
13222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
13232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
13242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        default:
13252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
13262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
13272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME magic number, should be configurable
13282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        numBuffers = 2;
13292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
13302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
13312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
13322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_ADDRESS:
13332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_IODEVICE:
13342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
13352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED5:
13362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
13372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_DATALOCATOR_RESERVED8:
13382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
1339d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
1340d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1341d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
1342d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pAudioSnk || (NULL == (SLuint32 *) pAudioSnk->pLocator))
1343d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1344d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    switch (*(SLuint32 *)pAudioSnk->pLocator) {
1345d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_OUTPUTMIX:
1346d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        {
13472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // pAudioSnk->pFormat is ignored
13482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLDataLocator_OutputMix *dl_outmix =
13492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            (SLDataLocator_OutputMix *) pAudioSnk->pLocator;
13502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLObjectItf outputMix = dl_outmix->outputMix;
1351d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        // FIXME make this an operation on Object: GetClass
13522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if ((NULL == outputMix) || (&OutputMix_class !=
13532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            ((struct Object_interface *) outputMix)->mClass))
1354d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
13552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct OutputMix_interface *om =
13562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            &((struct OutputMix_class *) outputMix)->mOutputMix;
13572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // allocate an entry within OutputMix for this track
13582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME O(n)
13592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned i;
13602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        for (i = 0, track = &om->mTracks[0]; i < 32; ++i, ++track) {
13612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (om->mActiveMask & (1 << i))
13622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
13632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            om->mActiveMask |= 1 << i;
13642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
13652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
13662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (32 <= i) {
13672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // FIXME Need a better error code for all slots full in output mix
13682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_MEMORY_FAILURE;
13692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
1370d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        }
1371d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        break;
1372d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
1373d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_URI:
1374d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_ADDRESS:
1375d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_IODEVICE:
1376d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED5:
1377d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
1378d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    case SL_DATALOCATOR_RESERVED8:
1379d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
1380d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    default:
1381d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1382d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
1383d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct AudioPlayer_class *this =
1384d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (struct AudioPlayer_class *) malloc(sizeof(struct AudioPlayer_class));
13852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
1386d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
13872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.itf = &AudioPlayer_ObjectItf;
1388d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.this = this;
1389d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mClass = &AudioPlayer_class;
1390d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
1391d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mCallback = NULL;
1392d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mContext = NULL;
1393d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.itf =
1394d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
1395d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.this = this;
1396d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.itf = &Play_PlayItf;
1397d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.this = this;
1398d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mPlay.mState = SL_PLAYSTATE_STOPPED;
13992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.mDuration = SL_TIME_UNKNOWN;
14002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.mPosition = (SLmillisecond) 0;
14012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // this->mPlay.mPositionSamples = 0;
1402d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.itf = &BufferQueue_BufferQueueItf;
1403d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.this = this;
1404d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mState.count = 0;
1405d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mState.playIndex = 0;
1406d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mCallback = NULL;
1407d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mContext = NULL;
14082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME numBuffers is unavailable for URL, must make a default !
1409d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mNumBuffers = numBuffers;
14102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mBufferQueue.mArray =
14112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        malloc((numBuffers + 1) * sizeof(struct BufferHeader));
1412d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    // assert(this->mBufferQueue.mArray != NULL);
1413d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mFront = this->mBufferQueue.mArray;
1414d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mBufferQueue.mRear = this->mBufferQueue.mArray;
1415d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.itf = &Volume_VolumeItf;
1416d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.this = this;
1417d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.mLevel = 0; // FIXME correct ?
14182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mMute = SL_BOOLEAN_FALSE;
14192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mEnableStereoPosition = SL_BOOLEAN_FALSE;
14202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mStereoPosition = 0;
14212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.itf = &Seek_SeekItf;
14222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.this = this;
14232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mPos = (SLmillisecond) -1;
14242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mLoopEnabled = SL_BOOLEAN_FALSE;
14252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mStartPos = (SLmillisecond) -1;
14262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mEndPos = (SLmillisecond) -1;
14272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SNDFILE
14282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mPathname = pathname;
14292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mSNDFILE = NULL;
14302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mIs0 = SL_BOOLEAN_TRUE;
14312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetryBuffer = NULL;
14322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSndFile.mRetrySize = 0;
14332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
14342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // link track to player
14352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mDfPcm = df_pcm;
14362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mBufferQueue = &this->mBufferQueue;
14372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mReader = NULL;
14382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mAvail = 0;
14392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    track->mPlay = &this->mPlay;
14402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new audio player object
1441d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pPlayer = &this->mObject.itf;
1442d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1443d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1444d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1445d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateAudioRecorder(SLEngineItf self,
1446d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk,
1447d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1448d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1449d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1450d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1451d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1452d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1453d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
1454d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
1455d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
1456d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1457d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
14582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pPlayer)
14592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
14602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pPlayer = NULL;
14612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = checkInterfaces(MidiPlayer_class.interfaces,
14622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        MidiPlayer_class.interfaceCount, numInterfaces, pInterfaceIds,
14632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pInterfaceRequired);
14642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
14652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
14662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pMIDISrc || NULL == pAudioOutput)
14672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
14682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct MidiPlayer_class *this =
14692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (struct MidiPlayer_class *) malloc(sizeof(struct MidiPlayer_class));
14702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this)
14712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
14722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.itf = &Object_ObjectItf;
14732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.this = this;
14742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mClass = &MidiPlayer_class;
14752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
14762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mCallback = NULL;
14772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mContext = NULL;
14782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.itf =
14792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
14802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.this = this;
14812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.itf = &Play_PlayItf;
14822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.this = this;
14832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.mState = SL_PLAYSTATE_STOPPED;
14842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.mDuration = SL_TIME_UNKNOWN;
14852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPlay.mPosition = 0;
14862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.itf = &Volume_VolumeItf;
14872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.this = this;
14882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mLevel = 0; // FIXME correct ?
14892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mMute = SL_BOOLEAN_FALSE;
14902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mEnableStereoPosition = SL_BOOLEAN_FALSE;
14912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mVolume.mStereoPosition = 0;
14922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.itf = &Seek_SeekItf;
14932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.this = this;
14942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mPos = (SLmillisecond) -1;
14952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mLoopEnabled = SL_BOOLEAN_FALSE;
14962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mStartPos = (SLmillisecond) -1;
14972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mSeek.mEndPos = (SLmillisecond) -1;
14982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // return the new MIDI player object
14992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pPlayer = &this->mObject.itf;
1500d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1501d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1502d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1503d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
1504d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1505d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1506d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1507d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1508d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1509d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1510d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup,
1511d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1512d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1513d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1514d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1515d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1516d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1517d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix,
1518d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1519d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1520d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1521d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == pMix)
1522d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1523d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLresult result = checkInterfaces(OutputMix_class.interfaces,
1524d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        OutputMix_class.interfaceCount, numInterfaces, pInterfaceIds,
1525d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        pInterfaceRequired);
1526d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (SL_RESULT_SUCCESS != result)
1527d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return result;
1528d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    struct OutputMix_class *this =
1529d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        (struct OutputMix_class *) malloc(sizeof(struct OutputMix_class));
1530d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    if (NULL == this) {
1531d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        *pMix = NULL;
1532d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_MEMORY_FAILURE;
1533d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
1534d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.itf = &Object_ObjectItf;
1535d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.this = this;
1536d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mClass = &OutputMix_class;
1537d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
1538d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mCallback = NULL;
1539d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mObject.mContext = NULL;
1540d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.itf =
1541d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
1542d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mDynamicInterfaceManagement.this = this;
1543d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mOutputMix.itf = &OutputMix_OutputMixItf;
1544d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mOutputMix.this = this;
15452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mOutputMix.mActiveMask = 0;
15462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = &this->mOutputMix.mTracks[0];
15472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME O(n)
15482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned i;
15492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    for (i = 0; i < 32; ++i, ++track)
15502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        track->mPlay = NULL;
1551d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.itf = &Volume_VolumeItf;
1552d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    this->mVolume.this = this;
1553d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    *pMix = &this->mObject.itf;
1554d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1555d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1556d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1557d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateMetadataExtractor(SLEngineItf self,
1558d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource,
1559d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1560d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1561d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1562d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1563d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1564d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1565d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_CreateExtensionObject(SLEngineItf self,
1566d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLObjectItf *pObject, void *pParameters, SLuint32 objectID,
1567d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
1568d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLboolean *pInterfaceRequired)
1569d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1570d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1571d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1572d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1573d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedInterfaces(SLEngineItf self,
1574d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
1575d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
1576d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1577d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1578d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1579d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic  SLresult Engine_QuerySupportedInterfaces(SLEngineItf self,
1580d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
1581d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
15822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
1583d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1584d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1585d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1586d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QueryNumSupportedExtensions(SLEngineItf self,
1587d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 *pNumExtensions)
1588d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
15892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
1590d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1591d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1592d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1593d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_QuerySupportedExtension(SLEngineItf self,
1594d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
1595d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
15962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
1597d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1598d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1599d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1600d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic SLresult Engine_IsExtensionSupported(SLEngineItf self,
1601d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    const SLchar *pExtensionName, SLboolean *pSupported)
1602d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
16032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
1604d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1605d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1606d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
1607d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kastenstatic const struct SLEngineItf_ Engine_EngineItf = {
1608d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateLEDDevice,
1609d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateVibraDevice,
1610d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioPlayer,
1611d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateAudioRecorder,
1612d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMidiPlayer,
1613d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateListener,
1614d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_Create3DGroup,
1615d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateOutputMix,
1616d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateMetadataExtractor,
1617d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_CreateExtensionObject,
1618d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedInterfaces,
1619d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedInterfaces,
1620d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QueryNumSupportedExtensions,
1621d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_QuerySupportedExtension,
1622d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    Engine_IsExtensionSupported
1623d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten};
1624d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
16252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioIODeviceCapabilities implementation */
1626d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
16272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioInputs(
16282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumInputs,
16292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pInputDeviceIDs)
1630d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
16312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
16332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
16342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioInputCapabilities(
16352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
16362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioInputDescriptor *pDescriptor)
16372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
16382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
16402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
16412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
16422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback(
16432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
16442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioInputsChangedCallback callback, void *pContext)
16452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
16462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
16482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
16492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAvailableAudioOutputs(
16502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumOutputs,
16512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
16522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
16532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumOutputs)
1654d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
16552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pOutputDeviceIDs) {
16562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // FIXME should be OEM-configurable
16572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (2 > *pNumOutputs)
16582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            return SL_RESULT_BUFFER_INSUFFICIENT;
16592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[0] = DEVICE_ID_HEADSET;
16602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pOutputDeviceIDs[1] = DEVICE_ID_HANDSFREE;
16612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
16622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNumOutputs = 2;
16632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
16652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
16662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QueryAudioOutputCapabilities(
16672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
16682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioOutputDescriptor *pDescriptor)
16692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
16702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDescriptor)
1671d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
16722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (deviceID) {
16732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME should be OEM-configurable
16742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HEADSET:
16752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_headset;
16762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
16772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case DEVICE_ID_HANDSFREE:
16782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pDescriptor = AudioOutputDescriptor_handsfree;
16792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
16802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
16812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_IO_ERROR;
1682d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    }
1683d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten    return SL_RESULT_SUCCESS;
1684d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1685d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
16862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult
16872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback(
16882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
16892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slAvailableAudioOutputsChangedCallback callback, void *pContext)
1690d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
16912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
16932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
16942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback(
16952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self,
16962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slDefaultDeviceIDMapChangedCallback callback, void *pContext)
16972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
16982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
16992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioInputs(
17022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
17032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioInputs, SLuint32 *pAudioInputDeviceIDs)
17042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetAssociatedAudioOutputs(
17092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
17102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioOutputs, SLuint32 *pAudioOutputDeviceIDs)
17112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_GetDefaultAudioDevices(
17162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 defaultDeviceID,
17172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumAudioDevices, SLuint32 *pAudioDeviceIDs)
17182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioIODeviceCapabilities_QuerySampleFormatsSupported(
17232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
17242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmilliHertz samplingRate, SLint32 *pSampleFormats,
17252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint32 *pNumOfSampleFormats)
17262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioIODeviceCapabilitiesItf_
17312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf = {
17322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioInputs,
17332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioInputCapabilities,
17342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback,
17352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAvailableAudioOutputs,
17362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QueryAudioOutputCapabilities,
17372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback,
17382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback,
17392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioInputs,
17402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetAssociatedAudioOutputs,
17412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_GetDefaultAudioDevices,
17422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioIODeviceCapabilities_QuerySampleFormatsSupported
17432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
17442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* OutputMix implementation */
17462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_GetDestinationOutputDeviceIDs(SLOutputMixItf self,
17482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten   SLint32 *pNumDevices, SLuint32 *pDeviceIDs)
17492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_RegisterDeviceChangeCallback(SLOutputMixItf self,
17542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slMixDeviceChangeCallback callback, void *pContext)
17552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult OutputMix_ReRoute(SLOutputMixItf self, SLint32 numOutputDevices,
17602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pOutputDeviceIDs)
17612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLOutputMixItf_ OutputMix_OutputMixItf = {
17662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_GetDestinationOutputDeviceIDs,
17672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_RegisterDeviceChangeCallback,
17682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_ReRoute
17692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
17702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Seek implementation */
17722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetPosition(SLSeekItf self, SLmillisecond pos,
17742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 seekMode)
17752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
17762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (seekMode) {
17772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_FAST:
17782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_SEEKMODE_ACCURATE:
17792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
17802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
1781d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
17822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
17832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
17842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mPos = pos;
17852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
1786d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1787d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
17882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_SetLoop(SLSeekItf self, SLboolean loopEnable,
17892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond startPos, SLmillisecond endPos)
1790d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
17912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
17922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mLoopEnabled = loopEnable;
17932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mStartPos = startPos;
17942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEndPos = endPos;
17952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
17962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
17972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
17982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Seek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
17992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillisecond *pStartPos, SLmillisecond *pEndPos)
18002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos)
1802d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
18032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Seek_interface *this = (struct Seek_interface *) self;
18042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pLoopEnabled = this->mLoopEnabled;
18052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStartPos = this->mStartPos;
18062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEndPos = this->mEndPos;
18072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
1808d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1809d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLSeekItf_ Seek_SeekItf = {
18112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetPosition,
18122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_SetLoop,
18132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Seek_GetLoop
18142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
1815d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DCommit implementation */
1817d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_Commit(SL3DCommitItf self)
1819d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
18202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
1822d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DCommit_SetDeferred(SL3DCommitItf self, SLboolean deferred)
18242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
1826d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
1827d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DCommitItf_ _3DCommit_3DCommitItf = {
18292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_Commit,
18302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DCommit_SetDeferred
18312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
18322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DDoppler implementation */
18342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DDopplerSetVelocityCartesian(SL3DDopplerItf self,
18362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pVelocity)
1837d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten{
18382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
1840d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DDopplerSetVelocitySpherical(SL3DDopplerItf self,
18422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter speed)
18432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
1846d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
18472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DDopplerGetVelocityCartesian(SL3DDopplerItf self,
18482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pVelocity)
18492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DDopplerSetDopplerFactor(SL3DDopplerItf self,
18542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille dopplerFactor)
18552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DDopplerGetDopplerFactor(SL3DDopplerItf self,
18602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pDopplerF)
18612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DDopplerItf_ _3DDoppler_3DDopplerItf = {
18662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DDopplerSetVelocityCartesian,
18672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DDopplerSetVelocitySpherical,
18682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DDopplerGetVelocityCartesian,
18692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DDopplerSetDopplerFactor,
18702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DDopplerGetDopplerFactor
18712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
18722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* 3DLocation implementation */
18742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationCartesian(SL3DLocationItf self,
18762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pLocation)
18772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetLocationSpherical(SL3DLocationItf self,
18822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance)
18832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
1885d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten}
18862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement)
18882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetLocationCartesian(SL3DLocationItf self,
18932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pLocation)
18942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
18952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
18962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
18972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
18982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationVectors(SL3DLocationItf self,
18992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pFront, const SLVec3D *pAbove)
19002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
19012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
19022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_SetOrientationAngles(SL3DLocationItf self,
19052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll)
19062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
19072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
19082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta,
19112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLVec3D *pAxis)
19122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
19132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
19142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult _3DLocation_GetOrientationVectors(SL3DLocationItf self,
19172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVec3D *pFront, SLVec3D *pUp)
19182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
19192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
19202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SL3DLocationItf_ _3DLocation_3DLocationItf = {
19232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationCartesian,
19242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetLocationSpherical,
19252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Move,
19262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetLocationCartesian,
19272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationVectors,
19282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_SetOrientationAngles,
19292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_Rotate,
19302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    _3DLocation_GetOrientationVectors
19312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
19322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioDecoderCapabilities implementation */
19342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME should build this table from Caps table below
19362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLuint32 Our_Decoder_IDs[] = {
19372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_PCM,
19382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_MP3,
19392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMR,
19402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWB,
19412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AMRWBPLUS,
19422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_AAC,
19432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_WMA,
19442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_REAL,
19452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME not in 1.0.1 header file
19462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define SL_AUDIOCODEC_VORBIS   ((SLuint32) 0x00000009)
19472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOCODEC_VORBIS
19482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
19492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define MAX_DECODERS (sizeof(Our_Decoder_IDs) / sizeof(Our_Decoder_IDs[0]))
19502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoders(
19522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 *pNumDecoders,
19532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pDecoderIds)
19542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
19552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNumDecoders)
19562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
19572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pDecoderIds)
19582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumDecoders = MAX_DECODERS;
19592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    else {
19602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLuint32 numDecoders = *pNumDecoders;
19612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (MAX_DECODERS < numDecoders) {
19622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            numDecoders = MAX_DECODERS;
19632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            *pNumDecoders = MAX_DECODERS;
19642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
19652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memcpy(pDecoderIds, Our_Decoder_IDs, numDecoders * sizeof(SLuint32));
19662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
19672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
19682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
19692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLmilliHertz Sample_Rates_PCM[] = {
19712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,
19722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_11_025,
19732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_12,
19742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_16,
19752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_22_05,
19762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_24,
19772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_32,
19782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_44_1,
19792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48
19802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
19812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
19822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const SLAudioCodecDescriptor Caps_PCM[] = {
19832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    {
19842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    2,                   // maxChannels
19852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    8,                   // minBitsPerSample
19862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    16,                  // maxBitsPerSample
19872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_8,   // minSampleRate
19882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_SAMPLINGRATE_48,  // maxSampleRate
19892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_FALSE,    // isFreqRangeContinuous
19902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    (SLmilliHertz *) Sample_Rates_PCM,
19912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // pSampleRatesSupported;
19922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    sizeof(Sample_Rates_PCM)/sizeof(Sample_Rates_PCM[0]),
19932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                         // numSampleRatesSupported
19942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    1,                   // minBitRate
19952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ~0,                  // maxBitRate
19962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_BOOLEAN_TRUE,     // isBitrateRangeContinuous
19972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    NULL,                // pBitratesSupported
19982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0,                   // numBitratesSupported
19992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SL_AUDIOPROFILE_PCM, // profileSetting
20002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    0                    // modeSetting
20012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
20022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct AudioDecoderCapabilities {
20052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mDecoderID;
20062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mNumCapabilities;
20072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLAudioCodecDescriptor *mDescriptors;
20082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten} Our_Decoder_Capabilities[] = {
20092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#define ENTRY(x) {SL_AUDIOCODEC_##x, sizeof(Caps_##x)/sizeof(Caps_##x[0]), Caps_##x}
20102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(PCM)
20112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#if 0
20122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(MP3),
20132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMR),
20142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWB),
20152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AMRWBPLUS),
20162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(AAC),
20172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(WMA),
20182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(REAL),
20192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ENTRY(VORBIS)
20202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#endif
20212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioDecoderCapabilities_GetAudioDecoderCapabilities(
20242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioDecoderCapabilitiesItf self, SLuint32 decoderId, SLuint32 *pIndex,
20252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
20262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioDecoderCapabilitiesItf_
20312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_AudioDecoderCapabilitiesItf = {
20322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoders,
20332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioDecoderCapabilities_GetAudioDecoderCapabilities
20342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoder implementation */
20372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_SetEncoderSettings(SLAudioEncoderItf self,
20392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings  *pSettings)
20402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoder_GetEncoderSettings(SLAudioEncoderItf self,
20452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderSettings *pSettings)
20462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioEncoderItf_ AudioEncoder_AudioEncoderItf = {
20512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_SetEncoderSettings,
20522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoder_GetEncoderSettings
20532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* AudioEncoderCapabilities implementation */
20562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoders(
20582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 *pNumEncoders, SLuint32 *pEncoderIds)
20592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult AudioEncoderCapabilities_GetAudioEncoderCapabilities(
20642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioEncoderCapabilitiesItf self, SLuint32 encoderId, SLuint32 *pIndex,
20652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLAudioCodecDescriptor *pDescriptor)
20662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLAudioEncoderCapabilitiesItf_
20712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_AudioEncoderCapabilitiesItf = {
20722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoders,
20732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    AudioEncoderCapabilities_GetAudioEncoderCapabilities
20742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
20752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DeviceVolume implementation */
20772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolumeScale(SLDeviceVolumeItf self,
20792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pMinValue, SLint32 *pMaxValue,
20802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsMillibelScale)
20812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMinValue)
20832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMinValue = 0;
20842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pMaxValue)
20852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pMaxValue = 10;
20862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsMillibelScale)
20872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsMillibelScale = SL_BOOLEAN_FALSE;
20882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_SetVolume(SLDeviceVolumeItf self,
20922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 volume)
20932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
20942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
20952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
20962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
20972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DeviceVolume_GetVolume(SLDeviceVolumeItf self,
20982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 deviceID, SLint32 *pVolume)
20992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLDeviceVolumeItf_ DeviceVolume_DeviceVolumeItf = {
21042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolumeScale,
21052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_SetVolume,
21062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DeviceVolume_GetVolume
21072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
21082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* DynamicSource implementation */
21102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult DynamicSource_SetSource(SLDynamicSourceItf self,
21122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLDataSource *pDataSource)
21132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLDynamicSourceItf_ DynamicSource_DynamicSourceItf = {
21182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    DynamicSource_SetSource
21192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
21202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EffectSend implementation */
21222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_EnableEffectSend(SLEffectSendItf self,
21242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean enable, SLmillibel initialLevel)
21252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_IsEnabled(SLEffectSendItf self,
21302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLboolean *pEnable)
21312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetDirectLevel(SLEffectSendItf self,
21362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel directLevel)
21372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetDirectLevel(SLEffectSendItf self,
21422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmillibel *pDirectLevel)
21432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_SetSendLevel(SLEffectSendItf self,
21482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel sendLevel)
21492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EffectSend_GetSendLevel(SLEffectSendItf self,
21542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const void *pAuxEffect, SLmillibel *pSendLevel)
21552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLEffectSendItf_ EffectSend_EffectSendItf = {
21602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_EnableEffectSend,
21612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_IsEnabled,
21622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetDirectLevel,
21632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetDirectLevel,
21642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_SetSendLevel,
21652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EffectSend_GetSendLevel
21662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
21672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* EngineCapabilities implementation */
21692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// FIXME for this and all others in this category
21712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QuerySupportedProfiles(
21732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported)
21742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pProfilesSupported)
21762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME This is pessimistic as it omits the unofficial driver profile
21782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pProfilesSupported = 0; // SL_PROFILES_PHONE | SL_PROFILES_MUSIC | SL_PROFILES_GAME
21792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
21802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
21812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
21822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAvailableVoices(
21832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 voiceType, SLint16 *pNumMaxVoices,
21842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices)
21852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
21862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    switch (voiceType) {
21872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_2D_AUDIO:
21882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_MIDI:
21892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_AUDIO:
21902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    case SL_VOICETYPE_3D_MIDIOUTPUT:
21912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        break;
21922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    default:
21932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
21942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
21952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumMaxVoices)
21962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumMaxVoices = 0;
21972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pIsAbsoluteMax)
21982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pIsAbsoluteMax = SL_BOOLEAN_TRUE;
21992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumFreeVoices)
22002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumFreeVoices = 0;
22012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryNumberOfMIDISynthesizers(
22052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLint16 *pNum)
22062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pNum)
22082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pNum = 0;
22102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self,
22142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep)
22152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!(NULL != pMajor && NULL != pMinor && NULL != pStep))
22172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMajor = 1;
22192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pMinor = 0;
22202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pStep = 1;
22212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryLEDCapabilities(
22252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pLEDDeviceID,
22262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLLEDDescriptor *pDescriptor)
22272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
22292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_QueryVibraCapabilities(
22332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLEngineCapabilitiesItf self, SLuint32 *pIndex, SLuint32 *pVibraDeviceID,
22342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVibraDescriptor *pDescriptor)
22352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME
22372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult EngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self,
22412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pIsThreadSafe)
22422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pIsThreadSafe)
22442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
22452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME For now
22462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pIsThreadSafe = SL_BOOLEAN_FALSE;
22472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLEngineCapabilitiesItf_
22512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_EngineCapabilitiesItf = {
22522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QuerySupportedProfiles,
22532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAvailableVoices,
22542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryNumberOfMIDISynthesizers,
22552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryAPIVersion,
22562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryLEDCapabilities,
22572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_QueryVibraCapabilities,
22582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    EngineCapabilities_IsThreadSafe
22592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
22602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* LEDArray implementation */
22622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult LEDArray_ActivateLEDArray(SLLEDArrayItf self, SLuint32 lightMask)
22642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult LEDArray_IsLEDArrayActivated(SLLEDArrayItf self,
22692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *lightMask)
22702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult LEDArray_SetColor(SLLEDArrayItf self, SLuint8 index,
22752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLHSL *color)
22762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult LEDArray_GetColor(SLLEDArrayItf self, SLuint8 index,
22812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLHSL *color)
22822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
22852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLLEDArrayItf_ LEDArray_LEDArrayItf = {
22872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    LEDArray_ActivateLEDArray,
22882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    LEDArray_IsLEDArrayActivated,
22892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    LEDArray_SetColor,
22902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    LEDArray_GetColor,
22912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
22922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* MetadataExtraction implementation */
22942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
22952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_GetItemCount(SLMetadataExtractionItf self,
22962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pItemCount)
22972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
22982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
22992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_GetKeySize(SLMetadataExtractionItf self,
23022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLuint32 *pKeySize)
23032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_GetKey(SLMetadataExtractionItf self,
23082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLuint32 keySize, SLMetadataInfo *pKey)
23092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_GetValueSize(SLMetadataExtractionItf self,
23142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLuint32 *pValueSize)
23152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_GetValue(SLMetadataExtractionItf self,
23202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLuint32 valueSize, SLMetadataInfo *pValue)
23212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_AddKeyFilter(SLMetadataExtractionItf self,
23262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 keySize, const void *pKey, SLuint32 keyEncoding,
23272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLchar *pValueLangCountry, SLuint32 valueEncoding, SLuint8 filterMask)
23282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataExtraction_ClearKeyFilter(SLMetadataExtractionItf self)
23332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMetadataExtractionItf_ MetadataExtraction_MetadataExtractionItf = {
23382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_GetItemCount,
23392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_GetKeySize,
23402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_GetKey,
23412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_GetValueSize,
23422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_GetValue,
23432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_AddKeyFilter,
23442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataExtraction_ClearKeyFilter
23452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
23462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* MetadataTraversal implementation */
23482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataTraversal_SetMode(SLMetadataTraversalItf self,
23502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 mode)
23512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataTraversal_GetChildCount(SLMetadataTraversalItf self,
23562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pCount)
23572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataTraversal_GetChildMIMETypeSize(SLMetadataTraversalItf self,
23622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLuint32 *pSize)
23632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataTraversal_GetChildInfo(SLMetadataTraversalItf self,
23682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index, SLint32 *pNodeID, SLuint32 *pType, SLuint32 size, SLchar *pMimeType)
23692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MetadataTraversal_SetActiveNode(SLMetadataTraversalItf self,
23742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 index)
23752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMetadataTraversalItf_ MetadataTraversal_MetadataTraversalItf = {
23802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataTraversal_SetMode,
23812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataTraversal_GetChildCount,
23822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataTraversal_GetChildMIMETypeSize,
23832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataTraversal_GetChildInfo,
23842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MetadataTraversal_SetActiveNode
23852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
23862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* MuteSolo implementation */
23882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan,
23902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten   SLboolean mute)
23912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
23942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
23952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan,
23962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pMute)
23972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
23982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
23992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
24022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean solo)
24032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan,
24082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean *pSolo)
24092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult MuteSolo_GetNumChannels(SLMuteSoloItf self,
24142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint8 *pNumChannels)
24152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLMuteSoloItf_ MuteSolo_MuteSoloItf = {
24202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MuteSolo_SetChannelMute,
24212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MuteSolo_GetChannelMute,
24222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MuteSolo_SetChannelSolo,
24232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MuteSolo_GetChannelSolo,
24242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    MuteSolo_GetNumChannels
24252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
24262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Pitch implementation */
24282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Pitch_SetPitch(SLPitchItf self, SLpermille pitch)
24302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Pitch_GetPitch(SLPitchItf self, SLpermille *pPitch)
24352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Pitch_GetPitchCapabilities(SLPitchItf self,
24402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pMinPitch, SLpermille *pMaxPitch)
24412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPitchItf_ Pitch_PitchItf = {
24462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Pitch_SetPitch,
24472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Pitch_GetPitch,
24482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Pitch_GetPitchCapabilities
24492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
24502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* PlaybackRate implementation */
24522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate)
24542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate)
24592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self,
24642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 constraints)
24652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_GetProperties(SLPlaybackRateItf self,
24702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pProperties)
24712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self,
24762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille rate, SLuint32 *pCapabilities)
24772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index,
24822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize,
24832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pCapabilities)
24842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
24852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
24862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
24872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPlaybackRateItf_ PlaybackRate_PlaybackRateItf = {
24892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_SetRate,
24902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_GetRate,
24912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_SetPropertyConstraints,
24922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_GetProperties,
24932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_GetCapabilitiesOfRate,
24942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PlaybackRate_GetRateRange
24952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
24962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* PrefetchStatus implementation */
24982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
24992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_GetPrefetchStatus(SLPrefetchStatusItf self,
25002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pStatus)
25012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_GetFillLevel(SLPrefetchStatusItf self,
25062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pLevel)
25072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_RegisterCallback(SLPrefetchStatusItf self,
25122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slPrefetchCallback callback, void *pContext)
25132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_SetCallbackEventsMask(SLPrefetchStatusItf self,
25182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 eventFlags)
25192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_GetCallbackEventsMask(SLPrefetchStatusItf self,
25242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pEventFlags)
25252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_SetFillUpdatePeriod(SLPrefetchStatusItf self,
25302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille period)
25312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult PrefetchStatus_GetFillUpdatePeriod(SLPrefetchStatusItf self,
25362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pPeriod)
25372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLPrefetchStatusItf_ PrefetchStatus_PrefetchStatusItf = {
25422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_GetPrefetchStatus,
25432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_GetFillLevel,
25442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_RegisterCallback,
25452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_SetCallbackEventsMask,
25462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_GetCallbackEventsMask,
25472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_SetFillUpdatePeriod,
25482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    PrefetchStatus_GetFillUpdatePeriod
25492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
25502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* RatePitch implementation */
25522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult RatePitch_SetRate(SLRatePitchItf self, SLpermille rate)
25542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult RatePitch_GetRate(SLRatePitchItf self, SLpermille *pRate)
25592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult RatePitch_GetRatePitchCapabilities(SLRatePitchItf self,
25642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate)
25652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLRatePitchItf_ RatePitch_RatePitchItf = {
25702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    RatePitch_SetRate,
25712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    RatePitch_GetRate,
25722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    RatePitch_GetRatePitchCapabilities
25732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
25742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Record implementation */
25762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_SetRecordState(SLRecordItf self, SLuint32 state)
25782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_GetRecordState(SLRecordItf self, SLuint32 *pState)
25832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_SetDurationLimit(SLRecordItf self, SLmillisecond msec)
25882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_GetPosition(SLRecordItf self, SLmillisecond *pMsec)
25932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
25942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
25952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
25962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
25972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_RegisterCallback(SLRecordItf self,
25982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    slRecordCallback callback, void *pContext)
25992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_SetCallbackEventsMask(SLRecordItf self,
26042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 eventFlags)
26052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_GetCallbackEventsMask(SLRecordItf self,
26102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pEventFlags)
26112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_SetMarkerPosition(SLRecordItf self, SLmillisecond mSec)
26162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_ClearMarkerPosition(SLRecordItf self)
26212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec)
26262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_SetPositionUpdatePeriod(SLRecordItf self, SLmillisecond mSec)
26312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Record_GetPositionUpdatePeriod(SLRecordItf self, SLmillisecond *pMsec)
26362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLRecordItf_ Record_RecordItf = {
26412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_SetRecordState,
26422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_GetRecordState,
26432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_SetDurationLimit,
26442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_GetPosition,
26452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_RegisterCallback,
26462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_SetCallbackEventsMask,
26472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_GetCallbackEventsMask,
26482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_SetMarkerPosition,
26492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_ClearMarkerPosition,
26502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_GetMarkerPosition,
26512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_SetPositionUpdatePeriod,
26522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Record_GetPositionUpdatePeriod
26532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
26542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* ThreadSync implementation */
26562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult ThreadSync_EnterCriticalSection(SLThreadSyncItf self)
26582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult ThreadSync_ExitCriticalSection(SLThreadSyncItf self)
26632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLThreadSyncItf_ ThreadSync_ThreadSyncItf = {
26682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ThreadSync_EnterCriticalSection,
26692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    ThreadSync_ExitCriticalSection
26702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
26712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Vibra implementation */
26732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_Vibrate(SLVibraItf self, SLboolean vibrate)
26752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_IsVibrating(SLVibraItf self, SLboolean *pVibrating)
26802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_SetFrequency(SLVibraItf self, SLmilliHertz frequency)
26852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_GetFrequency(SLVibraItf self, SLmilliHertz *pFrequency)
26902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_SetIntensity(SLVibraItf self, SLpermille intensity)
26952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
26962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
26972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
26982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
26992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Vibra_GetIntensity(SLVibraItf self, SLpermille *pIntensity)
27002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLVibraItf_ Vibra_VibraItf = {
27052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_Vibrate,
27062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_IsVibrating,
27072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_SetFrequency,
27082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_GetFrequency,
27092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_SetIntensity,
27102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Vibra_GetIntensity
27112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
27122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Visualization implementation */
27142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Visualization_RegisterVisualizationCallback(
27162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLVisualizationItf self, slVisualizationCallback callback, void *pContext,
27172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLmilliHertz rate)
27182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic SLresult Visualization_GetMaxRate(SLVisualizationItf self, SLmilliHertz* pRate)
27232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic const struct SLVisualizationItf_ Visualization_VisualizationItf = {
27282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Visualization_RegisterVisualizationCallback,
27292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    Visualization_GetMaxRate
27302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten};
27312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* Initial entry points */
27332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27342045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
27352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
27362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
27372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == pEngine)
27392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME why disallow a non-null pointer if num is 0
27412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if ((0 < numOptions) != (NULL != pEngineOptions))
27422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLresult result = checkInterfaces(Engine_class.interfaces,
27442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        Engine_class.interfaceCount, numInterfaces, pInterfaceIds,
27452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        pInterfaceRequired);
27462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SL_RESULT_SUCCESS != result)
27472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return result;
27482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Engine_class *this =
27492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (struct Engine_class *) malloc(sizeof(struct Engine_class));
27502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL == this) {
27512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pEngine = NULL;
27522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_MEMORY_FAILURE;
27532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
27542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.itf = &Object_ObjectItf;
27552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.this = this;
27562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mClass = &Engine_class;
27572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mState = SL_OBJECT_STATE_UNREALIZED;
27582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mCallback = NULL;
27592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mObject.mContext = NULL;
27602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.itf =
27612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        &DynamicInterfaceManagement_DynamicInterfaceManagementItf;
27622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mDynamicInterfaceManagement.this = this;
27632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEngine.itf = &Engine_EngineItf;
27642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mEngine.this = this;
27652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mAudioIODeviceCapabilities.itf =
27662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        &AudioIODeviceCapabilities_AudioIODeviceCapabilitiesItf;
27672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    this->mAudioIODeviceCapabilities.this = this;
27682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    *pEngine = &this->mObject.itf;
27692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    return SL_RESULT_SUCCESS;
27702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27722045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(
27732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLuint32 *pNumSupportedInterfaces)
27742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (NULL != pNumSupportedInterfaces) {
27762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pNumSupportedInterfaces = Engine_class.interfaceCount;
27772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_SUCCESS;
27782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    } else
27792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27822045b02407f6ac0a570faee3157b24317c8a69e0Glenn KastenSLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index,
27832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLInterfaceID *pInterfaceId)
27842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if ((index < sizeof(Engine_interfaces)/sizeof(Engine_interfaces[0])) &&
27862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        (NULL != pInterfaceId)) {
27872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        *pInterfaceId = *Engine_interfaces[index].iid;
27882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_SUCCESS;
27892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    } else
27902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
27912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
27922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten// Used by SDL but not specific to or dependent on SDL
27942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
27952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void OutputMix_FillBuffer(SLOutputMixItf self, void *pBuffer, SLuint32 size)
27962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
27972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // Force to be a multiple of a frame, assumes stereo 16-bit PCM
27982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    size &= ~3;
27992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct OutputMix_interface *this = (struct OutputMix_interface *) self;
28002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned activeMask = this->mActiveMask;
28012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct Track *track = &this->mTracks[0];
28022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    unsigned i;
28032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SLboolean mixBufferHasData = SL_BOOLEAN_FALSE;
28042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME O(32) loop even when few tracks are active.
28052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // To avoid loop, use activeMask to check for active track(s)
28062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // and decide whether we actually need to copy or mix.
28072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    for (i = 0; 0 != activeMask; ++i, ++track, activeMask >>= 1) {
28082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        assert(i < 32);
28092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (!(activeMask & 1))
28102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
28112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is allocated
28122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        struct Play_interface *play = track->mPlay;
28132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (NULL == play)
28142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
28152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is initialized
28162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (SL_PLAYSTATE_PLAYING != play->mState)
28172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            continue;
28182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        // track is playing
28192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        void *dstWriter = pBuffer;
28202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        unsigned desired = size;
28212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        SLboolean trackContributedToMix = SL_BOOLEAN_FALSE;
28222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        while (desired > 0) {
28232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            struct BufferQueue_interface *bufferQueue;
28242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            const struct BufferHeader *oldFront, *newFront, *rear;
28252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            unsigned actual = desired;
28262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (track->mAvail < actual)
28272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                actual = track->mAvail;
28282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // force actual to be a frame multiple
28292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (actual > 0) {
28302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME check for either mute or volume 0
28312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // in which case skip the input buffer processing
28322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                assert(NULL != track->mReader);
28332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME && gain == 1.0
28342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (mixBufferHasData) {
28352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    typedef struct {
28362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        short left;
28372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        short right;
28382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    } stereo;
28392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    stereo *mixBuffer = dstWriter;
28402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    const stereo *source = track->mReader;
28412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    unsigned j;
28422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    for (j = 0; j < actual; j += sizeof(stereo), ++mixBuffer, ++source) {
28432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // apply gain here
28442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->left += source->left;
28452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        mixBuffer->right += source->right;
28462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
28472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                } else {
28482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    memcpy(dstWriter, track->mReader, actual);
28492045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    trackContributedToMix = SL_BOOLEAN_TRUE;
28502045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
28512045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                dstWriter = (char *) dstWriter + actual;
28522045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                desired -= actual;
28532045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mReader = (char *) track->mReader + actual;
28542045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                track->mAvail -= actual;
28552045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (track->mAvail == 0) {
28562045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    bufferQueue = track->mBufferQueue;
28572045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (NULL != bufferQueue) {
28582045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        oldFront = bufferQueue->mFront;
28592045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        rear = bufferQueue->mRear;
28602045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(oldFront != rear);
28612045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        newFront = oldFront;
28622045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        if (++newFront == &bufferQueue->mArray[bufferQueue->mNumBuffers])
28632045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                            newFront = bufferQueue->mArray;
28642045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        bufferQueue->mFront = (struct BufferHeader *) newFront;
28652045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        assert(0 < bufferQueue->mState.count);
28662045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        --bufferQueue->mState.count;
28672045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // FIXME here or in Enqueue?
28682045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        ++bufferQueue->mState.playIndex;
28692045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // FIXME this might be a good time to do an early warning
28702045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        // callback depending on buffer count
28712045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    }
28722045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
28732045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                continue;
28742045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
28752045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // actual == 0
28762045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            bufferQueue = track->mBufferQueue;
28772045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (NULL != bufferQueue) {
28782045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                oldFront = bufferQueue->mFront;
28792045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                rear = bufferQueue->mRear;
28802045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (oldFront != rear) {
28812045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastengot_one:
28822045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    assert(0 < bufferQueue->mState.count);
28832045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mReader = oldFront->mBuffer;
28842045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    track->mAvail = oldFront->mSize;
28852045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    continue;
28862045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
28872045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME should be able to configure when to
28882045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // kick off the callback e.g. high/low water-marks etc.
28892045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // We need data but none available, attempting a desperate callback
28902045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                slBufferQueueCallback callback = bufferQueue->mCallback;
28912045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                if (NULL != callback) {
28922045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    (*callback)((SLBufferQueueItf) bufferQueue, bufferQueue->mContext);
28932045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    // if we are lucky, maybe the callback enqueued a buffer
28942045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    // we got lucky, now the queue is not empty, the callback worked
28952045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    if (rear != bufferQueue->mRear)
28962045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                        goto got_one;
28972045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                    // callback was unsuccessful, underflow seems our only recourse
28982045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                }
28992045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // here on underflow due to no callback, or failed callback
29002045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // FIXME underflow, send silence (or previous buffer?)
29012045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // we did a callback to try to kick start again but failed
29022045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                // should log this
29032045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            }
29042045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            // here if no buffer queue or underflow, clear out rest of partial buffer
29052045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            if (!mixBufferHasData && trackContributedToMix)
29062045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten                memset(dstWriter, 0, actual);
29072045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            break;
29082045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        }
29092045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        if (trackContributedToMix)
29102045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten            mixBufferHasData = SL_BOOLEAN_TRUE;
29112045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
29122045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // No active tracks, so output silence
29132045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (!mixBufferHasData)
29142045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        memset(pBuffer, 0, size);
29152045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29162045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29172045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten#ifdef USE_SDL
29182045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29192045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten/* SDL platform implementation */
29202045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29212045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenstatic void SDLCALL SDL_callback(void *context, Uint8 *stream, int len)
29222045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
29232045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    assert(len > 0);
29242045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    OutputMix_FillBuffer((SLOutputMixItf) context, stream, (SLuint32) len);
29252045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29262045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29272045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kastenvoid SDL_start(SLObjectItf self)
29282045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten{
29292045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    assert(self != NULL);
29302045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    // FIXME make this an operation on Object: GetClass
29312045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    assert(&OutputMix_class == ((struct Object_interface *) self)->mClass);
29322045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    struct OutputMix_interface *om = &((struct OutputMix_class *) self)->mOutputMix;
29332045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29342045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_AudioSpec fmt;
29352045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.freq = 44100;
29362045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.format = AUDIO_S16;
29372045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.channels = 2;
29382045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.samples = 256;
29392045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.callback = SDL_callback;
29402045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    fmt.userdata = om;
29412045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
29422045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    if (SDL_OpenAudio(&fmt, NULL) < 0) {
29432045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
29442045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten        exit(1);
29452045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    }
29462045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten    SDL_PauseAudio(0);
29472045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten}
29482045b02407f6ac0a570faee3157b24317c8a69e0Glenn Kasten
2949d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten#endif
2950d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten
2951d7143537437acbd4b97761a1c5bf852be9ba485aGlenn Kasten/* End */
2952