IEngine.c revision acd88797a1d3b8225bab888d29036e245f275be5
19d10b341a0ba46f108cb96e46691197d778cbc06San Mehat/*
29d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Copyright (C) 2010 The Android Open Source Project
39d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
49d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
59d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * you may not use this file except in compliance with the License.
69d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * You may obtain a copy of the License at
79d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
89d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
99d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Unless required by applicable law or agreed to in writing, software
119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * See the License for the specific language governing permissions and
149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * limitations under the License.
159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat */
169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat/* Engine implementation */
189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "sles_allinclusive.h"
209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
219d10b341a0ba46f108cb96e46691197d778cbc06San Mehatstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat{
249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (NULL == pDevice || SL_DEFAULTDEVICEID_LED != deviceID)
259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return SL_RESULT_PARAMETER_INVALID;
269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    *pDevice = NULL;
279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    unsigned exposedMask;
289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    SLresult result = checkInterfaces(pCLEDDevice_class, numInterfaces,
309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        pInterfaceIds, pInterfaceRequired, &exposedMask);
319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (SL_RESULT_SUCCESS != result)
329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return result;
339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (NULL == this)
359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return SL_RESULT_MEMORY_FAILURE;
369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    SLHSL *color = (SLHSL *) malloc(sizeof(SLHSL) * this->mLEDArray.mCount);
379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    assert(NULL != this->mLEDArray.mColor);
389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    this->mLEDArray.mColor = color;
399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    unsigned i;
403208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt    for (i = 0; i < this->mLEDArray.mCount; ++i) {
413208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        // per specification 1.0.1 pg. 259: "Default color is undefined."
429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        color->hue = 0;
439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        color->saturation = 1000;
449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        color->lightness = 1000;
459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    this->mDeviceID = deviceID;
479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    *pDevice = &this->mObject.mItf;
489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return SL_RESULT_SUCCESS;
499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
519d10b341a0ba46f108cb96e46691197d778cbc06San Mehatstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat{
54    if (NULL == pDevice || SL_DEFAULTDEVICEID_VIBRA != deviceID)
55        return SL_RESULT_PARAMETER_INVALID;
56    *pDevice = NULL;
57    unsigned exposedMask;
58    const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
59    SLresult result = checkInterfaces(pCVibraDevice_class, numInterfaces,
60        pInterfaceIds, pInterfaceRequired, &exposedMask);
61    if (SL_RESULT_SUCCESS != result)
62        return result;
63    CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
64    if (NULL == this)
65        return SL_RESULT_MEMORY_FAILURE;
66    this->mDeviceID = deviceID;
67    *pDevice = &this->mObject.mItf;
68    return SL_RESULT_SUCCESS;
69}
70
71static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
72    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
73    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
74{
75    fprintf(stderr, "entering IEngine_CreateAudioPlayer()\n");
76
77    if (NULL == pPlayer)
78        return SL_RESULT_PARAMETER_INVALID;
79    *pPlayer = NULL;
80    unsigned exposedMask;
81    const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
82    SLresult result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
83        pInterfaceIds, pInterfaceRequired, &exposedMask);
84    if (SL_RESULT_SUCCESS != result)
85        return result;
86
87    // Construct our new AudioPlayer instance
88    CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
89    if (NULL == this) {
90        return SL_RESULT_MEMORY_FAILURE;
91    }
92
93    // Check the source and sink parameters against generic constraints,
94    // and make a local copy of all parameters in case other application threads
95    // change memory concurrently.
96
97    result = checkDataSource(pAudioSrc, &this->mDataSource);
98    if (SL_RESULT_SUCCESS != result)
99        goto abort;
100
101    result = checkDataSink(pAudioSnk, &this->mDataSink);
102    if (SL_RESULT_SUCCESS != result)
103        goto abort;
104
105    fprintf(stderr, "\t after checkDataSource()/Sink()\n");
106
107    // check the audio source and sink parameters against platform support
108
109#ifdef USE_ANDROID
110    result = sles_to_android_checkAudioPlayerSourceSink(this);
111    if (SL_RESULT_SUCCESS != result)
112        goto abort;
113    fprintf(stderr, "\t after sles_to_android_checkAudioPlayerSourceSink()\n");
114#endif
115
116#ifdef USE_SNDFILE
117    result = SndFile_checkAudioPlayerSourceSink(this);
118    if (SL_RESULT_SUCCESS != result)
119        goto abort;
120#endif
121
122#ifdef USE_OUTPUTMIXEXT
123    result = IOutputMixExt_checkAudioPlayerSourceSink(this);
124    if (SL_RESULT_SUCCESS != result)
125        goto abort;
126#endif
127
128    // Allocate memory for buffer queue
129    //if (0 != this->mBufferQueue.mNumBuffers) {
130        // inline allocation of circular mArray, up to a typical max
131        if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) {
132            this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
133        } else {
134            // FIXME integer overflow possible during multiplication
135            this->mBufferQueue.mArray = (struct BufferHeader *)
136                    malloc((this->mBufferQueue.mNumBuffers + 1) * sizeof(struct BufferHeader));
137            if (NULL == this->mBufferQueue.mArray) {
138                result = SL_RESULT_MEMORY_FAILURE;
139                goto abort;
140            }
141        }
142        this->mBufferQueue.mFront = this->mBufferQueue.mArray;
143        this->mBufferQueue.mRear = this->mBufferQueue.mArray;
144    //}
145
146    // used to store the data source of our audio player
147    this->mDynamicSource.mDataSource = &this->mDataSource.u.mSource;
148
149    // platform-specific initialization
150
151#ifdef USE_ANDROID
152    sles_to_android_audioPlayerCreate(this);
153#endif
154
155    // return the new audio player object
156    *pPlayer = &this->mObject.mItf;
157    return SL_RESULT_SUCCESS;
158
159abort:
160    freeDataLocatorFormat(&this->mDataSource);
161    freeDataLocatorFormat(&this->mDataSink);
162    if ((NULL != this->mBufferQueue.mArray) &&
163        (this->mBufferQueue.mTypical != this->mBufferQueue.mArray)) {
164            free(this->mBufferQueue.mArray);
165    }
166    free(this);
167    return result;
168}
169
170static SLresult IEngine_CreateAudioRecorder(SLEngineItf self,
171    SLObjectItf *pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk,
172    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
173    const SLboolean *pInterfaceRequired)
174{
175    if (NULL == pRecorder)
176        return SL_RESULT_PARAMETER_INVALID;
177    *pRecorder = NULL;
178    unsigned exposedMask;
179    const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
180    SLresult result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
181        pInterfaceIds, pInterfaceRequired, &exposedMask);
182    if (SL_RESULT_SUCCESS != result)
183        return result;
184
185    // DataSource checks
186    DataLocatorFormat myDataSource;
187    result = checkDataSource(pAudioSrc, &myDataSource);
188    if (SL_RESULT_SUCCESS != result)
189        return result;
190
191    // DataSink checks
192    DataLocatorFormat myDataSink;
193    result = checkDataSink(pAudioSnk, &myDataSink);
194    if (SL_RESULT_SUCCESS != result) {
195        freeDataLocatorFormat(&myDataSink);
196        return result;
197    }
198
199    return SL_RESULT_SUCCESS;
200}
201
202static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
203    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
204    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
205    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
206{
207    if (NULL == pPlayer)
208        return SL_RESULT_PARAMETER_INVALID;
209    *pPlayer = NULL;
210    unsigned exposedMask;
211    const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
212    SLresult result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
213        pInterfaceIds, pInterfaceRequired, &exposedMask);
214    if (SL_RESULT_SUCCESS != result)
215        return result;
216    if (NULL == pMIDISrc || NULL == pAudioOutput)
217        return SL_RESULT_PARAMETER_INVALID;
218    CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
219    if (NULL == this)
220        return SL_RESULT_MEMORY_FAILURE;
221    // return the new MIDI player object
222    *pPlayer = &this->mObject.mItf;
223    return SL_RESULT_SUCCESS;
224}
225
226static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
227    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
228    const SLboolean *pInterfaceRequired)
229{
230    if (NULL == pListener)
231        return SL_RESULT_PARAMETER_INVALID;
232    *pListener = NULL;
233    unsigned exposedMask;
234    const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
235    SLresult result = checkInterfaces(pCListener_class, numInterfaces,
236        pInterfaceIds, pInterfaceRequired, &exposedMask);
237    if (SL_RESULT_SUCCESS != result)
238        return result;
239    return SL_RESULT_FEATURE_UNSUPPORTED;
240}
241
242static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup,
243    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
244    const SLboolean *pInterfaceRequired)
245{
246    if (NULL == pGroup)
247        return SL_RESULT_PARAMETER_INVALID;
248    *pGroup = NULL;
249    unsigned exposedMask;
250    const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
251    SLresult result = checkInterfaces(pC3DGroup_class, numInterfaces,
252        pInterfaceIds, pInterfaceRequired, &exposedMask);
253    if (SL_RESULT_SUCCESS != result)
254        return result;
255    return SL_RESULT_FEATURE_UNSUPPORTED;
256}
257
258static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix,
259    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
260    const SLboolean *pInterfaceRequired)
261{
262    if (NULL == pMix)
263        return SL_RESULT_PARAMETER_INVALID;
264    *pMix = NULL;
265    unsigned exposedMask;
266    const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
267    SLresult result = checkInterfaces(pCOutputMix_class, numInterfaces,
268        pInterfaceIds, pInterfaceRequired, &exposedMask);
269    if (SL_RESULT_SUCCESS != result)
270        return result;
271    COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
272    if (NULL == this)
273        return SL_RESULT_MEMORY_FAILURE;
274    *pMix = &this->mObject.mItf;
275    return SL_RESULT_SUCCESS;
276}
277
278static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self,
279    SLObjectItf *pMetadataExtractor, SLDataSource *pDataSource,
280    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
281    const SLboolean *pInterfaceRequired)
282{
283    if (NULL == pMetadataExtractor)
284        return SL_RESULT_PARAMETER_INVALID;
285    *pMetadataExtractor = NULL;
286    unsigned exposedMask;
287    const ClassTable *pCMetadataExtractor_class = objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
288    SLresult result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
289        pInterfaceIds, pInterfaceRequired, &exposedMask);
290    if (SL_RESULT_SUCCESS != result)
291        return result;
292    CMetadataExtractor *this = (CMetadataExtractor *)
293        construct(pCMetadataExtractor_class, exposedMask, self);
294    if (NULL == this)
295        return SL_RESULT_MEMORY_FAILURE;
296    *pMetadataExtractor = &this->mObject.mItf;
297    return SL_RESULT_SUCCESS;
298}
299
300static SLresult IEngine_CreateExtensionObject(SLEngineItf self,
301    SLObjectItf *pObject, void *pParameters, SLuint32 objectID,
302    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
303    const SLboolean *pInterfaceRequired)
304{
305    if (NULL == pObject)
306        return SL_RESULT_PARAMETER_INVALID;
307    *pObject = NULL;
308    return SL_RESULT_FEATURE_UNSUPPORTED;
309}
310
311static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
312    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
313{
314    if (NULL == pNumSupportedInterfaces)
315        return SL_RESULT_PARAMETER_INVALID;
316    const ClassTable *class__ = objectIDtoClass(objectID);
317    if (NULL == class__)
318        return SL_RESULT_FEATURE_UNSUPPORTED;
319    *pNumSupportedInterfaces = class__->mInterfaceCount;
320    return SL_RESULT_SUCCESS;
321}
322
323static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
324    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
325{
326    if (NULL == pInterfaceId)
327        return SL_RESULT_PARAMETER_INVALID;
328    const ClassTable *class__ = objectIDtoClass(objectID);
329    if (NULL == class__)
330        return SL_RESULT_FEATURE_UNSUPPORTED;
331    if (index >= class__->mInterfaceCount)
332        return SL_RESULT_PARAMETER_INVALID;
333    *pInterfaceId = &SL_IID_array[class__->mInterfaces[index].mMPH];
334    return SL_RESULT_SUCCESS;
335};
336
337static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self,
338    SLuint32 *pNumExtensions)
339{
340    if (NULL == pNumExtensions)
341        return SL_RESULT_PARAMETER_INVALID;
342    *pNumExtensions = 0;
343    return SL_RESULT_SUCCESS;
344}
345
346static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
347    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
348{
349    // any index >= 0 will be >= number of supported extensions
350    return SL_RESULT_PARAMETER_INVALID;
351}
352
353static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
354    const SLchar *pExtensionName, SLboolean *pSupported)
355{
356    if (NULL == pExtensionName || NULL == pSupported)
357        return SL_RESULT_PARAMETER_INVALID;
358    *pSupported = SL_BOOLEAN_FALSE;
359    return SL_RESULT_SUCCESS;
360}
361
362static const struct SLEngineItf_ IEngine_Itf = {
363    IEngine_CreateLEDDevice,
364    IEngine_CreateVibraDevice,
365    IEngine_CreateAudioPlayer,
366    IEngine_CreateAudioRecorder,
367    IEngine_CreateMidiPlayer,
368    IEngine_CreateListener,
369    IEngine_Create3DGroup,
370    IEngine_CreateOutputMix,
371    IEngine_CreateMetadataExtractor,
372    IEngine_CreateExtensionObject,
373    IEngine_QueryNumSupportedInterfaces,
374    IEngine_QuerySupportedInterfaces,
375    IEngine_QueryNumSupportedExtensions,
376    IEngine_QuerySupportedExtension,
377    IEngine_IsExtensionSupported
378};
379
380void IEngine_init(void *self)
381{
382    IEngine *this = (IEngine *) self;
383    this->mItf = &IEngine_Itf;
384    // mLossOfControlGlobal is initialized in CreateEngine
385    this->mInstanceCount = 0;
386    unsigned i;
387    for (i = 0; i < INSTANCE_MAX; ++i)
388        this->mInstances[i] = NULL;
389}
390