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