IEngine.c revision 928ea4ffff40c82987cfb1ac9e3095fdc6968709
1e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter/*
2e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * Copyright (C) 2010 The Android Open Source Project
3e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter *
4e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * Licensed under the Apache License, Version 2.0 (the "License");
5e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * you may not use this file except in compliance with the License.
6e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * You may obtain a copy of the License at
7e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter *
8e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter *      http://www.apache.org/licenses/LICENSE-2.0
9e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter *
10e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * Unless required by applicable law or agreed to in writing, software
11e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * distributed under the License is distributed on an "AS IS" BASIS,
12e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * See the License for the specific language governing permissions and
14e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter * limitations under the License.
15e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter */
16e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala/* Engine implementation */
184bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala
19e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#include "sles_allinclusive.h"
20e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
21e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
22e538206d15282afbc5b168d60b1026a5dfcd13c0James Painterstatic SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
23e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
24e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter{
25e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SL_ENTER_INTERFACE
26e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
27e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef USE_OPTIONAL
28e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
29e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        result = SL_RESULT_PARAMETER_INVALID;
30e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    } else {
31e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        *pDevice = NULL;
32e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        unsigned exposedMask;
33e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
34e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
35e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            pInterfaceRequired, &exposedMask);
36e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        if (SL_RESULT_SUCCESS == result) {
37e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            CLEDDevice *this = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
38e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            if (NULL == this) {
39e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                result = SL_RESULT_MEMORY_FAILURE;
40e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            } else {
41e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                this->mDeviceID = deviceID;
42e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                *pDevice = &this->mObject.mItf;
43e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            }
44e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        }
45e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    }
46e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#else
47e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    result = SL_RESULT_FEATURE_UNSUPPORTED;
48e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
49e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
50e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SL_LEAVE_INTERFACE
51e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter}
52e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
53e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
54e538206d15282afbc5b168d60b1026a5dfcd13c0James Painterstatic SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
55e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
56e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter{
57e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SL_ENTER_INTERFACE
58e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
59e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef USE_OPTIONAL
60e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
61e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        result = SL_RESULT_PARAMETER_INVALID;
62e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    } else {
63e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        *pDevice = NULL;
64e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        unsigned exposedMask;
65e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
66e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        result = checkInterfaces(pCVibraDevice_class, numInterfaces,
67e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            pInterfaceIds, pInterfaceRequired, &exposedMask);
68e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        if (SL_RESULT_SUCCESS == result) {
69e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            CVibraDevice *this = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
70e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            if (NULL == this) {
71e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                result = SL_RESULT_MEMORY_FAILURE;
72e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            } else {
73e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                this->mDeviceID = deviceID;
74e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                *pDevice = &this->mObject.mItf;
75e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            }
76e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        }
77e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    }
78e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#else
79e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    result = SL_RESULT_FEATURE_UNSUPPORTED;
80e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
81e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
82e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SL_LEAVE_INTERFACE
83e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter}
84e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
85e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
86e538206d15282afbc5b168d60b1026a5dfcd13c0James Painterstatic SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
87e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
88e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
89e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter{
90e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    SL_ENTER_INTERFACE
91e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
92e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    if (NULL == pPlayer) {
93e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter       result = SL_RESULT_PARAMETER_INVALID;
94e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    } else {
95e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        *pPlayer = NULL;
96e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        unsigned exposedMask;
97e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
98e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
99e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            pInterfaceIds, pInterfaceRequired, &exposedMask);
100e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        if (SL_RESULT_SUCCESS == result) {
101e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
102e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            // Construct our new AudioPlayer instance
103e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            CAudioPlayer *this = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
104e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            if (NULL == this) {
105e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                result = SL_RESULT_MEMORY_FAILURE;
106e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            } else {
107e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
108e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                do {
109e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
110e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // Initialize private fields not associated with an interface
111e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mOutputMix = NULL;
112e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mMuteMask = 0;
113e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mSoloMask = 0;
114e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // const, will be set later by the containing AudioPlayer or MidiPlayer
115e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mNumChannels = 0;
116e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mSampleRateMilliHz = 0;
117e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
118e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // Check the source and sink parameters against generic constraints,
119e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // and make a local copy of all parameters in case other application threads
120e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // change memory concurrently.
121e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
122e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = checkDataSource(pAudioSrc, &this->mDataSource);
123e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
124e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
125e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
126e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
127e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = checkSourceFormatVsInterfacesCompatibility(&this->mDataSource,
128e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            numInterfaces, pInterfaceIds, pInterfaceRequired);
129e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
130e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
131e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
132e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
133e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = checkDataSink(pAudioSnk, &this->mDataSink, SL_OBJECTID_AUDIOPLAYER);
134e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
135e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
136e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
137e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
138e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // copy the buffer queue count from source locator to the buffer queue interface
139e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // we have already range-checked the value down to a smaller width
140e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
141e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    this->mBufferQueue.mNumBuffers = (SL_DATALOCATOR_BUFFERQUEUE == *(SLuint32 *)
142e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        pAudioSrc->pLocator) ? (SLuint16) ((SLDataLocator_BufferQueue *)
143e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        pAudioSrc->pLocator)->numBuffers : 0;
144e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
145e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // link this audio player to its associated output mix via a strong reference
146e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_DATALOCATOR_OUTPUTMIX == this->mDataSink.mLocator.mLocatorType) {
147e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        this->mOutputMix = (COutputMix *)
148e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            this->mDataSink.mLocator.mOutputMix.outputMix;
149e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
150e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
151e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // check the audio source and sink parameters against platform support
152e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef ANDROID
153e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = android_audioPlayer_checkSourceSink(this);
154e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
155e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
156e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
157e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
158e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
159e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef USE_SNDFILE
160e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = SndFile_checkAudioPlayerSourceSink(this);
161e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
162e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
163e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
164e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
165e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
166e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef USE_OUTPUTMIXEXT
167e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    result = IOutputMixExt_checkAudioPlayerSourceSink(this);
168e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    if (SL_RESULT_SUCCESS != result) {
169e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        break;
170e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    }
171e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
172e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
173e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // FIXME move to dedicated function
174e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // Allocate memory for buffer queue
175e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
176e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    //if (0 != this->mBufferQueue.mNumBuffers) {
177e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        // inline allocation of circular mArray, up to a typical max
178e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) {
179e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
180e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        } else {
181e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            // Avoid possible integer overflow during multiplication; this arbitrary
182e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            // maximum is big enough to not interfere with real applications, but
183e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            // small enough to not overflow.
184e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            if (this->mBufferQueue.mNumBuffers >= 256) {
185e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                                result = SL_RESULT_MEMORY_FAILURE;
186e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                                break;
187e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            }
188e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            this->mBufferQueue.mArray = (BufferHeader *) malloc((this->mBufferQueue.
189e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                                mNumBuffers + 1) * sizeof(BufferHeader));
190e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            if (NULL == this->mBufferQueue.mArray) {
191e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                                result = SL_RESULT_MEMORY_FAILURE;
192e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                                break;
193e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                            }
194e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        }
195e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        this->mBufferQueue.mFront = this->mBufferQueue.mArray;
196e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        this->mBufferQueue.mRear = this->mBufferQueue.mArray;
197e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        //}
198e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
199e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        // used to store the data source of our audio player
200e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        this->mDynamicSource.mDataSource = &this->mDataSource.u.mSource;
201e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
202e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        // platform-specific initialization
203e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#ifdef ANDROID
204e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        android_audioPlayer_create(this);
205e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter#endif
206e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
207e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        // return the new audio player object
208e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                        *pPlayer = &this->mObject.mItf;
209e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
210e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                } while (0);
211e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
212e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                if (SL_RESULT_SUCCESS != result) {
213e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    (*this->mObject.mItf->Destroy)(&this->mObject.mItf);
214e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                    // equivalent to calling IObject_Destroy directly
215e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter                }
216e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
217e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter            }
218e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter        }
219e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter
220e538206d15282afbc5b168d60b1026a5dfcd13c0James Painter    }
221
222    SL_LEAVE_INTERFACE
223}
224
225
226static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
227    SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
228    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
229{
230    SL_ENTER_INTERFACE
231
232    SL_LOGV("IEngine_CreateAudioRecorder() entering");
233
234#if defined(USE_OPTIONAL) || defined(ANDROID)
235    if (NULL == pRecorder) {
236        result = SL_RESULT_PARAMETER_INVALID;
237    } else {
238        *pRecorder = NULL;
239        unsigned exposedMask;
240        const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
241        result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
242                pInterfaceIds, pInterfaceRequired, &exposedMask);
243
244        if (SL_RESULT_SUCCESS == result) {
245
246            // Construct our new AudioRecorder instance
247            CAudioRecorder *this = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
248                    self);
249            if (NULL == this) {
250                result = SL_RESULT_MEMORY_FAILURE;
251            } else {
252
253                do {
254                    // const, will be set later by the containing AudioRecorder
255                    this->mNumChannels = 0;
256                    this->mSampleRateMilliHz = 0;
257
258                    // Check the source and sink parameters, and make a local copy of all parameters
259                    result = checkDataSource(pAudioSrc, &this->mDataSource);
260                    if (SL_RESULT_SUCCESS != result) {
261                        break;
262                    }
263                    result = checkDataSink(pAudioSnk, &this->mDataSink, SL_OBJECTID_AUDIORECORDER);
264                    if (SL_RESULT_SUCCESS != result) {
265                        break;
266                    }
267
268                    // check the audio source and sink parameters against platform support
269#ifdef ANDROID
270                    result = android_audioRecorder_checkSourceSinkSupport(this);
271                    if (SL_RESULT_SUCCESS != result) {
272                        SL_LOGE("Android: Cannot create AudioRecorder: invalid source or sink");
273                        break;
274                    }
275#endif
276
277#ifdef ANDROID
278                    // FIXME move to dedicated function
279                    SLuint32 locatorType = *(SLuint32 *) pAudioSnk->pLocator;
280                    if (locatorType == SL_DATALOCATOR_BUFFERQUEUE) {
281                        this->mBufferQueue.mNumBuffers = ((SLDataLocator_BufferQueue *)
282                                pAudioSnk->pLocator)->numBuffers;
283                        // inline allocation of circular Buffer Queue mArray, up to a typical max
284                        if (BUFFER_HEADER_TYPICAL >= this->mBufferQueue.mNumBuffers) {
285                            this->mBufferQueue.mArray = this->mBufferQueue.mTypical;
286                        } else {
287                            // Avoid possible integer overflow during multiplication; this arbitrary
288                            // maximum is big enough to not interfere with real applications, but
289                            // small enough to not overflow.
290                            if (this->mBufferQueue.mNumBuffers >= 256) {
291                                result = SL_RESULT_MEMORY_FAILURE;
292                                break;
293                            }
294                            this->mBufferQueue.mArray = (BufferHeader *) malloc((this->mBufferQueue.
295                                    mNumBuffers + 1) * sizeof(BufferHeader));
296                            if (NULL == this->mBufferQueue.mArray) {
297                                result = SL_RESULT_MEMORY_FAILURE;
298                                break;
299                            }
300                        }
301                        this->mBufferQueue.mFront = this->mBufferQueue.mArray;
302                        this->mBufferQueue.mRear = this->mBufferQueue.mArray;
303                    }
304#endif
305
306                    // platform-specific initialization
307#ifdef ANDROID
308                    android_audioRecorder_create(this);
309#endif
310
311                    // return the new audio recorder object
312                    *pRecorder = &this->mObject.mItf;
313
314                } while (0);
315
316                if (SL_RESULT_SUCCESS != result) {
317                    (*this->mObject.mItf->Destroy)(&this->mObject.mItf);
318                    // equivalent to calling IObject_Destroy directly
319                }
320            }
321
322        }
323
324    }
325#else
326    result = SL_RESULT_FEATURE_UNSUPPORTED;
327#endif
328
329    SL_LEAVE_INTERFACE
330}
331
332
333static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
334    SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
335    SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
336    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
337{
338    SL_ENTER_INTERFACE
339
340#if defined(USE_GAME) || defined(USE_PHONE)
341    if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
342        result = SL_RESULT_PARAMETER_INVALID;
343    } else {
344        *pPlayer = NULL;
345        unsigned exposedMask;
346        const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
347        result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
348            pInterfaceIds, pInterfaceRequired, &exposedMask);
349        if (SL_RESULT_SUCCESS == result) {
350            CMidiPlayer *this = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
351            if (NULL == this) {
352                result = SL_RESULT_MEMORY_FAILURE;
353            } else {
354                // return the new MIDI player object
355                *pPlayer = &this->mObject.mItf;
356                // FIXME a fake value - why not use value from IPlay_init? what does CT check for?
357                this->mPlay.mDuration = 0;
358            }
359        }
360    }
361#else
362    result = SL_RESULT_FEATURE_UNSUPPORTED;
363#endif
364
365    SL_LEAVE_INTERFACE
366}
367
368
369static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
370    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
371{
372    SL_ENTER_INTERFACE
373
374#ifdef USE_GAME
375    if (NULL == pListener) {
376        result = SL_RESULT_PARAMETER_INVALID;
377    } else {
378        *pListener = NULL;
379        unsigned exposedMask;
380        const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
381        result = checkInterfaces(pCListener_class, numInterfaces,
382            pInterfaceIds, pInterfaceRequired, &exposedMask);
383        if (SL_RESULT_SUCCESS == result) {
384            CListener *this = (CListener *) construct(pCListener_class, exposedMask, self);
385            if (NULL == this) {
386                result = SL_RESULT_MEMORY_FAILURE;
387            } else {
388                // return the new listener object
389                *pListener = &this->mObject.mItf;
390            }
391        }
392    }
393#else
394    result = SL_RESULT_FEATURE_UNSUPPORTED;
395#endif
396
397    SL_LEAVE_INTERFACE
398}
399
400
401static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
402    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
403{
404    SL_ENTER_INTERFACE
405
406#ifdef USE_GAME
407    if (NULL == pGroup) {
408        result = SL_RESULT_PARAMETER_INVALID;
409    } else {
410        *pGroup = NULL;
411        unsigned exposedMask;
412        const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
413        result = checkInterfaces(pC3DGroup_class, numInterfaces,
414            pInterfaceIds, pInterfaceRequired, &exposedMask);
415        if (SL_RESULT_SUCCESS == result) {
416            C3DGroup *this = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
417            if (NULL == this) {
418                result = SL_RESULT_MEMORY_FAILURE;
419            } else {
420                this->mMemberMask = 0;
421                // return the new 3DGroup object
422                *pGroup = &this->mObject.mItf;
423            }
424        }
425    }
426#else
427    result = SL_RESULT_FEATURE_UNSUPPORTED;
428#endif
429
430    SL_LEAVE_INTERFACE
431}
432
433
434static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
435    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
436{
437    SL_ENTER_INTERFACE
438
439    if (NULL == pMix) {
440        result = SL_RESULT_PARAMETER_INVALID;
441    } else {
442        *pMix = NULL;
443        unsigned exposedMask;
444        const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
445        result = checkInterfaces(pCOutputMix_class, numInterfaces,
446            pInterfaceIds, pInterfaceRequired, &exposedMask);
447        if (SL_RESULT_SUCCESS == result) {
448            COutputMix *this = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
449            if (NULL == this) {
450                result = SL_RESULT_MEMORY_FAILURE;
451            } else {
452                *pMix = &this->mObject.mItf;
453            }
454        }
455    }
456
457    SL_LEAVE_INTERFACE
458}
459
460
461static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
462    SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
463    const SLboolean *pInterfaceRequired)
464{
465    SL_ENTER_INTERFACE
466
467#if defined(USE_GAME) || defined(USE_MUSIC)
468    if (NULL == pMetadataExtractor) {
469        result = SL_RESULT_PARAMETER_INVALID;
470    } else {
471        *pMetadataExtractor = NULL;
472        unsigned exposedMask;
473        const ClassTable *pCMetadataExtractor_class =
474            objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
475        result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
476            pInterfaceIds, pInterfaceRequired, &exposedMask);
477        if (SL_RESULT_SUCCESS == result) {
478            CMetadataExtractor *this = (CMetadataExtractor *)
479                construct(pCMetadataExtractor_class, exposedMask, self);
480            if (NULL == this) {
481                result = SL_RESULT_MEMORY_FAILURE;
482            } else {
483                *pMetadataExtractor = &this->mObject.mItf;
484                result = SL_RESULT_SUCCESS;
485            }
486        }
487    }
488#else
489    result = SL_RESULT_FEATURE_UNSUPPORTED;
490#endif
491
492    SL_LEAVE_INTERFACE
493}
494
495
496static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
497    void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
498    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
499{
500    SL_ENTER_INTERFACE
501
502    if (NULL == pObject) {
503        result = SL_RESULT_PARAMETER_INVALID;
504    } else {
505        *pObject = NULL;
506        result = SL_RESULT_FEATURE_UNSUPPORTED;
507    }
508
509    SL_LEAVE_INTERFACE
510}
511
512
513static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
514    SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
515{
516    SL_ENTER_INTERFACE
517
518    if (NULL == pNumSupportedInterfaces) {
519        result = SL_RESULT_PARAMETER_INVALID;
520    } else {
521        const ClassTable *class__ = objectIDtoClass(objectID);
522        if (NULL == class__) {
523            result = SL_RESULT_FEATURE_UNSUPPORTED;
524        } else {
525            SLuint32 count = 0;
526            SLuint32 i;
527            for (i = 0; i < class__->mInterfaceCount; ++i) {
528                switch (class__->mInterfaces[i].mInterface) {
529                case INTERFACE_IMPLICIT:
530                case INTERFACE_EXPLICIT:
531                case INTERFACE_DYNAMIC:
532                    ++count;
533                    break;
534                case INTERFACE_UNAVAILABLE:
535                    break;
536                default:
537                    assert(false);
538                    break;
539                }
540            }
541            *pNumSupportedInterfaces = count;
542            result = SL_RESULT_SUCCESS;
543        }
544    }
545
546    SL_LEAVE_INTERFACE;
547}
548
549
550static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
551    SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
552{
553    SL_ENTER_INTERFACE
554
555    if (NULL == pInterfaceId) {
556        result = SL_RESULT_PARAMETER_INVALID;
557    } else {
558        *pInterfaceId = NULL;
559        const ClassTable *class__ = objectIDtoClass(objectID);
560        if (NULL == class__) {
561            result = SL_RESULT_FEATURE_UNSUPPORTED;
562        } else {
563            result = SL_RESULT_PARAMETER_INVALID; // will be reset later
564            SLuint32 i;
565            for (i = 0; i < class__->mInterfaceCount; ++i) {
566                switch (class__->mInterfaces[i].mInterface) {
567                case INTERFACE_IMPLICIT:
568                case INTERFACE_EXPLICIT:
569                case INTERFACE_DYNAMIC:
570                    break;
571                case INTERFACE_UNAVAILABLE:
572                    continue;
573                default:
574                    assert(false);
575                    break;
576                }
577                if (index == 0) {
578                    *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH];
579                    result = SL_RESULT_SUCCESS;
580                    break;
581                }
582                --index;
583            }
584        }
585    }
586
587    SL_LEAVE_INTERFACE
588};
589
590
591static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
592{
593    SL_ENTER_INTERFACE
594
595    if (NULL == pNumExtensions) {
596        result = SL_RESULT_PARAMETER_INVALID;
597    } else {
598        *pNumExtensions = 0;
599        result = SL_RESULT_SUCCESS;
600    }
601
602    SL_LEAVE_INTERFACE
603}
604
605
606static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
607    SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
608{
609    SL_ENTER_INTERFACE
610
611    // any index >= 0 will be >= number of supported extensions
612    result = SL_RESULT_PARAMETER_INVALID;
613
614    SL_LEAVE_INTERFACE
615}
616
617
618static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
619    const SLchar *pExtensionName, SLboolean *pSupported)
620{
621    SL_ENTER_INTERFACE
622
623    if (NULL == pExtensionName || NULL == pSupported) {
624        result = SL_RESULT_PARAMETER_INVALID;
625    } else {
626        // no extensions are supported
627        *pSupported = SL_BOOLEAN_FALSE;
628        result = SL_RESULT_SUCCESS;
629    }
630
631    SL_LEAVE_INTERFACE
632}
633
634
635static const struct SLEngineItf_ IEngine_Itf = {
636    IEngine_CreateLEDDevice,
637    IEngine_CreateVibraDevice,
638    IEngine_CreateAudioPlayer,
639    IEngine_CreateAudioRecorder,
640    IEngine_CreateMidiPlayer,
641    IEngine_CreateListener,
642    IEngine_Create3DGroup,
643    IEngine_CreateOutputMix,
644    IEngine_CreateMetadataExtractor,
645    IEngine_CreateExtensionObject,
646    IEngine_QueryNumSupportedInterfaces,
647    IEngine_QuerySupportedInterfaces,
648    IEngine_QueryNumSupportedExtensions,
649    IEngine_QuerySupportedExtension,
650    IEngine_IsExtensionSupported
651};
652
653void IEngine_init(void *self)
654{
655    IEngine *this = (IEngine *) self;
656    this->mItf = &IEngine_Itf;
657    // mLossOfControlGlobal is initialized in CreateEngine
658#ifdef USE_SDL
659    this->mOutputMix = NULL;
660#endif
661    this->mInstanceCount = 1; // ourself
662    this->mInstanceMask = 0;
663    this->mChangedMask = 0;
664    unsigned i;
665    for (i = 0; i < MAX_INSTANCE; ++i) {
666        this->mInstances[i] = NULL;
667    }
668    this->mShutdown = SL_BOOLEAN_FALSE;
669    this->mShutdownAck = SL_BOOLEAN_FALSE;
670#if defined(ANDROID) && !defined(USE_BACKPORT)
671    this->mEqNumPresets = 0;
672    this->mEqPresetNames = NULL;
673#endif
674}
675