1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "sles_allinclusive.h"
18 
19 /* AudioIODeviceCapabilities implementation */
20 
21 // NTH make it platform-configurable
22 
23 
IAudioIODeviceCapabilities_GetAvailableAudioInputs(SLAudioIODeviceCapabilitiesItf self,SLint32 * pNumInputs,SLuint32 * pInputDeviceIDs)24 static SLresult IAudioIODeviceCapabilities_GetAvailableAudioInputs(
25     SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumInputs, SLuint32 *pInputDeviceIDs)
26 {
27     SL_ENTER_INTERFACE
28 
29     if (NULL == pNumInputs) {
30         result = SL_RESULT_PARAMETER_INVALID;
31     } else {
32         result = SL_RESULT_SUCCESS;
33         if (NULL != pInputDeviceIDs) {
34             if (1 > *pNumInputs) {
35                 result = SL_RESULT_BUFFER_INSUFFICIENT;
36             } else {
37                 pInputDeviceIDs[0] = SL_DEFAULTDEVICEID_AUDIOINPUT;
38             }
39         }
40         *pNumInputs = 1;
41     }
42 
43     SL_LEAVE_INTERFACE
44 }
45 
46 
IAudioIODeviceCapabilities_QueryAudioInputCapabilities(SLAudioIODeviceCapabilitiesItf self,SLuint32 deviceID,SLAudioInputDescriptor * pDescriptor)47 static SLresult IAudioIODeviceCapabilities_QueryAudioInputCapabilities(
48     SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, SLAudioInputDescriptor *pDescriptor)
49 {
50     SL_ENTER_INTERFACE
51 
52     if (NULL == pDescriptor) {
53         result = SL_RESULT_PARAMETER_INVALID;
54     } else {
55         result = SL_RESULT_SUCCESS;
56         switch (deviceID) {
57         case SL_DEFAULTDEVICEID_AUDIOINPUT:
58             *pDescriptor = *AudioInput_id_descriptors[0].descriptor;
59             break;
60         default:
61             result = SL_RESULT_IO_ERROR;
62             break;
63         }
64     }
65 
66     SL_LEAVE_INTERFACE
67 }
68 
69 
IAudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback(SLAudioIODeviceCapabilitiesItf self,slAvailableAudioInputsChangedCallback callback,void * pContext)70 static SLresult IAudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback(
71     SLAudioIODeviceCapabilitiesItf self, slAvailableAudioInputsChangedCallback callback,
72     void *pContext)
73 {
74     SL_ENTER_INTERFACE
75 
76     IAudioIODeviceCapabilities * thiz = (IAudioIODeviceCapabilities *) self;
77     interface_lock_exclusive(thiz);
78     thiz->mAvailableAudioInputsChangedCallback = callback;
79     thiz->mAvailableAudioInputsChangedContext = pContext;
80     interface_unlock_exclusive(thiz);
81     result = SL_RESULT_SUCCESS;
82 
83     SL_LEAVE_INTERFACE
84 }
85 
86 
IAudioIODeviceCapabilities_GetAvailableAudioOutputs(SLAudioIODeviceCapabilitiesItf self,SLint32 * pNumOutputs,SLuint32 * pOutputDeviceIDs)87 static SLresult IAudioIODeviceCapabilities_GetAvailableAudioOutputs(
88     SLAudioIODeviceCapabilitiesItf self, SLint32 *pNumOutputs, SLuint32 *pOutputDeviceIDs)
89 {
90     SL_ENTER_INTERFACE
91 
92     if (NULL == pNumOutputs) {
93         result = SL_RESULT_PARAMETER_INVALID;
94     } else {
95         result = SL_RESULT_SUCCESS;
96         if (NULL != pOutputDeviceIDs) {
97             if (2 > *pNumOutputs) {
98                 result = SL_RESULT_BUFFER_INSUFFICIENT;
99                 // if 1 slot available, should still fill that
100             } else {
101                 pOutputDeviceIDs[0] = DEVICE_ID_HEADSET;
102                 pOutputDeviceIDs[1] = DEVICE_ID_HANDSFREE;
103                 // SL_DEFAULTDEVICEID_AUDIOOUTPUT?
104             }
105         }
106         *pNumOutputs = 2;
107     }
108 
109     SL_LEAVE_INTERFACE
110 }
111 
112 
IAudioIODeviceCapabilities_QueryAudioOutputCapabilities(SLAudioIODeviceCapabilitiesItf self,SLuint32 deviceID,SLAudioOutputDescriptor * pDescriptor)113 static SLresult IAudioIODeviceCapabilities_QueryAudioOutputCapabilities(
114     SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, SLAudioOutputDescriptor *pDescriptor)
115 {
116     SL_ENTER_INTERFACE
117 
118     if (NULL == pDescriptor) {
119         result = SL_RESULT_PARAMETER_INVALID;
120     } else {
121         result = SL_RESULT_SUCCESS;
122         switch (deviceID) {
123         case DEVICE_ID_HEADSET:
124             *pDescriptor = *AudioOutput_id_descriptors[1].descriptor;
125             break;
126         case DEVICE_ID_HANDSFREE:
127             *pDescriptor = *AudioOutput_id_descriptors[2].descriptor;
128             break;
129         // SL_DEFAULTDEVICEID_AUDIOOUTPUT?
130         default:
131             result = SL_RESULT_IO_ERROR;
132             break;
133         }
134     }
135 
136     SL_LEAVE_INTERFACE
137 }
138 
139 
IAudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback(SLAudioIODeviceCapabilitiesItf self,slAvailableAudioOutputsChangedCallback callback,void * pContext)140 static SLresult IAudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback(
141     SLAudioIODeviceCapabilitiesItf self, slAvailableAudioOutputsChangedCallback callback,
142     void *pContext)
143 {
144     SL_ENTER_INTERFACE
145 
146     IAudioIODeviceCapabilities * thiz = (IAudioIODeviceCapabilities *) self;
147     interface_lock_exclusive(thiz);
148     thiz->mAvailableAudioOutputsChangedCallback = callback;
149     thiz->mAvailableAudioOutputsChangedContext = pContext;
150     interface_unlock_exclusive(thiz);
151     result = SL_RESULT_SUCCESS;
152 
153     SL_LEAVE_INTERFACE
154 }
155 
156 
IAudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback(SLAudioIODeviceCapabilitiesItf self,slDefaultDeviceIDMapChangedCallback callback,void * pContext)157 static SLresult IAudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback(
158     SLAudioIODeviceCapabilitiesItf self, slDefaultDeviceIDMapChangedCallback callback,
159     void *pContext)
160 {
161     SL_ENTER_INTERFACE
162 
163     IAudioIODeviceCapabilities * thiz = (IAudioIODeviceCapabilities *) self;
164     interface_lock_exclusive(thiz);
165     thiz->mDefaultDeviceIDMapChangedCallback = callback;
166     thiz->mDefaultDeviceIDMapChangedContext = pContext;
167     interface_unlock_exclusive(thiz);
168     result = SL_RESULT_SUCCESS;
169 
170     SL_LEAVE_INTERFACE
171 }
172 
173 
IAudioIODeviceCapabilities_GetAssociatedAudioInputs(SLAudioIODeviceCapabilitiesItf self,SLuint32 deviceID,SLint32 * pNumAudioInputs,SLuint32 * pAudioInputDeviceIDs)174 static SLresult IAudioIODeviceCapabilities_GetAssociatedAudioInputs(
175     SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
176     SLint32 *pNumAudioInputs, SLuint32 *pAudioInputDeviceIDs)
177 {
178     SL_ENTER_INTERFACE
179 
180     if (NULL == pNumAudioInputs) {
181         result = SL_RESULT_PARAMETER_INVALID;
182     } else {
183         // Incomplete
184         *pNumAudioInputs = 0;
185         result = SL_RESULT_SUCCESS;
186     }
187 
188     SL_LEAVE_INTERFACE
189 }
190 
191 
IAudioIODeviceCapabilities_GetAssociatedAudioOutputs(SLAudioIODeviceCapabilitiesItf self,SLuint32 deviceID,SLint32 * pNumAudioOutputs,SLuint32 * pAudioOutputDeviceIDs)192 static SLresult IAudioIODeviceCapabilities_GetAssociatedAudioOutputs(
193     SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID,
194     SLint32 *pNumAudioOutputs, SLuint32 *pAudioOutputDeviceIDs)
195 {
196     SL_ENTER_INTERFACE
197 
198     if (NULL == pNumAudioOutputs) {
199         result = SL_RESULT_PARAMETER_INVALID;
200     } else {
201         // Incomplete
202         *pNumAudioOutputs = 0;
203         result = SL_RESULT_SUCCESS;
204     }
205 
206     SL_LEAVE_INTERFACE
207 }
208 
209 
IAudioIODeviceCapabilities_GetDefaultAudioDevices(SLAudioIODeviceCapabilitiesItf self,SLuint32 defaultDeviceID,SLint32 * pNumAudioDevices,SLuint32 * pAudioDeviceIDs)210 static SLresult IAudioIODeviceCapabilities_GetDefaultAudioDevices(
211     SLAudioIODeviceCapabilitiesItf self, SLuint32 defaultDeviceID,
212     SLint32 *pNumAudioDevices, SLuint32 *pAudioDeviceIDs)
213 {
214     SL_ENTER_INTERFACE
215 
216     if (NULL == pNumAudioDevices) {
217         result = SL_RESULT_PARAMETER_INVALID;
218     } else {
219         switch (defaultDeviceID) {
220         case SL_DEFAULTDEVICEID_AUDIOINPUT:
221         case SL_DEFAULTDEVICEID_AUDIOOUTPUT:
222             result = SL_RESULT_SUCCESS;
223             if (NULL != pAudioDeviceIDs) {
224                 switch (defaultDeviceID) {
225                 case SL_DEFAULTDEVICEID_AUDIOINPUT:
226                     if (1 > *pNumAudioDevices) {
227                         result = SL_RESULT_BUFFER_INSUFFICIENT;
228                     } else {
229                         pAudioDeviceIDs[0] = SL_DEFAULTDEVICEID_AUDIOINPUT;
230                     }
231                     *pNumAudioDevices = 1;
232                     break;
233                 case SL_DEFAULTDEVICEID_AUDIOOUTPUT:
234                     if (2 > *pNumAudioDevices) {
235                         result = SL_RESULT_BUFFER_INSUFFICIENT;
236                     } else {
237                         pAudioDeviceIDs[0] = DEVICE_ID_HEADSET;
238                         pAudioDeviceIDs[1] = DEVICE_ID_HANDSFREE;
239                         // should be capable of returning first item if 1 slot
240                     }
241                     *pNumAudioDevices = 2;
242                     break;
243                 default:
244                     assert(SL_BOOLEAN_FALSE);
245                     *pNumAudioDevices = 0;
246                     break;
247                 }
248             }
249             break;
250         default:
251             result = SL_RESULT_IO_ERROR;
252             break;
253         }
254     }
255 
256     SL_LEAVE_INTERFACE
257 }
258 
259 
IAudioIODeviceCapabilities_QuerySampleFormatsSupported(SLAudioIODeviceCapabilitiesItf self,SLuint32 deviceID,SLmilliHertz samplingRate,SLint32 * pSampleFormats,SLint32 * pNumOfSampleFormats)260 static SLresult IAudioIODeviceCapabilities_QuerySampleFormatsSupported(
261     SLAudioIODeviceCapabilitiesItf self, SLuint32 deviceID, SLmilliHertz samplingRate,
262     SLint32 *pSampleFormats, SLint32 *pNumOfSampleFormats)
263 {
264     SL_ENTER_INTERFACE
265 
266     if (NULL == pNumOfSampleFormats) {
267         result = SL_RESULT_PARAMETER_INVALID;
268     } else {
269         switch (deviceID) {
270         case SL_DEFAULTDEVICEID_AUDIOINPUT:
271         case SL_DEFAULTDEVICEID_AUDIOOUTPUT:
272             result = SL_RESULT_SUCCESS;
273             // incomplete
274             switch (samplingRate) {
275             case SL_SAMPLINGRATE_44_1:
276                 break;
277             default:
278                 result = SL_RESULT_IO_ERROR;
279                 break;
280             }
281             if (NULL != pSampleFormats) {
282                 if (1 > *pNumOfSampleFormats)
283                     result = SL_RESULT_BUFFER_INSUFFICIENT;
284                 // incomplete
285                 pSampleFormats[0] = SL_PCMSAMPLEFORMAT_FIXED_16;
286             }
287             *pNumOfSampleFormats = 1;
288             break;
289         default:
290             result = SL_RESULT_IO_ERROR;
291             break;
292         }
293     }
294 
295     SL_LEAVE_INTERFACE
296 }
297 
298 
299 static const struct SLAudioIODeviceCapabilitiesItf_ IAudioIODeviceCapabilities_Itf = {
300     IAudioIODeviceCapabilities_GetAvailableAudioInputs,
301     IAudioIODeviceCapabilities_QueryAudioInputCapabilities,
302     IAudioIODeviceCapabilities_RegisterAvailableAudioInputsChangedCallback,
303     IAudioIODeviceCapabilities_GetAvailableAudioOutputs,
304     IAudioIODeviceCapabilities_QueryAudioOutputCapabilities,
305     IAudioIODeviceCapabilities_RegisterAvailableAudioOutputsChangedCallback,
306     IAudioIODeviceCapabilities_RegisterDefaultDeviceIDMapChangedCallback,
307     IAudioIODeviceCapabilities_GetAssociatedAudioInputs,
308     IAudioIODeviceCapabilities_GetAssociatedAudioOutputs,
309     IAudioIODeviceCapabilities_GetDefaultAudioDevices,
310     IAudioIODeviceCapabilities_QuerySampleFormatsSupported
311 };
312 
IAudioIODeviceCapabilities_init(void * self)313 void IAudioIODeviceCapabilities_init(void *self)
314 {
315     IAudioIODeviceCapabilities *thiz = (IAudioIODeviceCapabilities *) self;
316     thiz->mItf = &IAudioIODeviceCapabilities_Itf;
317     thiz->mAvailableAudioInputsChangedCallback = NULL;
318     thiz->mAvailableAudioInputsChangedContext = NULL;
319     thiz->mAvailableAudioOutputsChangedCallback = NULL;
320     thiz->mAvailableAudioOutputsChangedContext = NULL;
321     thiz->mDefaultDeviceIDMapChangedCallback = NULL;
322     thiz->mDefaultDeviceIDMapChangedContext = NULL;
323 }
324