1 /*
2 * Copyright 2016 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 #define LOG_TAG "AAudio"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20
21 #include <cutils/properties.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <utils/Errors.h>
25
26 #include "aaudio/AAudio.h"
27 #include "core/AudioGlobal.h"
28 #include <aaudio/AAudioTesting.h>
29 #include <math.h>
30 #include <system/audio.h>
31 #include <assert.h>
32
33 #include "utility/AAudioUtilities.h"
34
35 using namespace android;
36
AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result)37 status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
38 // This covers the case for AAUDIO_OK and for positive results.
39 if (result >= 0) {
40 return result;
41 }
42 status_t status;
43 switch (result) {
44 case AAUDIO_ERROR_DISCONNECTED:
45 case AAUDIO_ERROR_NO_SERVICE:
46 status = DEAD_OBJECT;
47 break;
48 case AAUDIO_ERROR_INVALID_HANDLE:
49 status = BAD_TYPE;
50 break;
51 case AAUDIO_ERROR_INVALID_STATE:
52 status = INVALID_OPERATION;
53 break;
54 case AAUDIO_ERROR_INVALID_RATE:
55 case AAUDIO_ERROR_INVALID_FORMAT:
56 case AAUDIO_ERROR_ILLEGAL_ARGUMENT:
57 case AAUDIO_ERROR_OUT_OF_RANGE:
58 status = BAD_VALUE;
59 break;
60 case AAUDIO_ERROR_WOULD_BLOCK:
61 status = WOULD_BLOCK;
62 break;
63 case AAUDIO_ERROR_NULL:
64 status = UNEXPECTED_NULL;
65 break;
66 case AAUDIO_ERROR_UNAVAILABLE:
67 status = NOT_ENOUGH_DATA;
68 break;
69
70 // TODO translate these result codes
71 case AAUDIO_ERROR_INTERNAL:
72 case AAUDIO_ERROR_UNIMPLEMENTED:
73 case AAUDIO_ERROR_NO_FREE_HANDLES:
74 case AAUDIO_ERROR_NO_MEMORY:
75 case AAUDIO_ERROR_TIMEOUT:
76 default:
77 status = UNKNOWN_ERROR;
78 break;
79 }
80 return status;
81 }
82
AAudioConvert_androidToAAudioResult(status_t status)83 aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) {
84 // This covers the case for OK and for positive result.
85 if (status >= 0) {
86 return status;
87 }
88 aaudio_result_t result;
89 switch (status) {
90 case BAD_TYPE:
91 result = AAUDIO_ERROR_INVALID_HANDLE;
92 break;
93 case DEAD_OBJECT:
94 result = AAUDIO_ERROR_NO_SERVICE;
95 break;
96 case INVALID_OPERATION:
97 result = AAUDIO_ERROR_INVALID_STATE;
98 break;
99 case UNEXPECTED_NULL:
100 result = AAUDIO_ERROR_NULL;
101 break;
102 case BAD_VALUE:
103 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
104 break;
105 case WOULD_BLOCK:
106 result = AAUDIO_ERROR_WOULD_BLOCK;
107 break;
108 case NOT_ENOUGH_DATA:
109 result = AAUDIO_ERROR_UNAVAILABLE;
110 break;
111 default:
112 result = AAUDIO_ERROR_INTERNAL;
113 break;
114 }
115 return result;
116 }
117
AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId)118 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) {
119 // If not a regular sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE.
120 return (sessionId == AAUDIO_SESSION_ID_ALLOCATE || sessionId == AAUDIO_SESSION_ID_NONE)
121 ? AUDIO_SESSION_ALLOCATE
122 : (audio_session_t) sessionId;
123 }
124
AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat)125 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) {
126 audio_format_t androidFormat;
127 switch (aaudioFormat) {
128 case AAUDIO_FORMAT_UNSPECIFIED:
129 androidFormat = AUDIO_FORMAT_DEFAULT;
130 break;
131 case AAUDIO_FORMAT_PCM_I16:
132 androidFormat = AUDIO_FORMAT_PCM_16_BIT;
133 break;
134 case AAUDIO_FORMAT_PCM_FLOAT:
135 androidFormat = AUDIO_FORMAT_PCM_FLOAT;
136 break;
137 case AAUDIO_FORMAT_PCM_I24_PACKED:
138 androidFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
139 break;
140 case AAUDIO_FORMAT_PCM_I32:
141 androidFormat = AUDIO_FORMAT_PCM_32_BIT;
142 break;
143 default:
144 androidFormat = AUDIO_FORMAT_INVALID;
145 ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
146 break;
147 }
148 return androidFormat;
149 }
150
AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat)151 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
152 aaudio_format_t aaudioFormat;
153 switch (androidFormat) {
154 case AUDIO_FORMAT_DEFAULT:
155 aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
156 break;
157 case AUDIO_FORMAT_PCM_16_BIT:
158 aaudioFormat = AAUDIO_FORMAT_PCM_I16;
159 break;
160 case AUDIO_FORMAT_PCM_FLOAT:
161 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
162 break;
163 case AUDIO_FORMAT_PCM_24_BIT_PACKED:
164 aaudioFormat = AAUDIO_FORMAT_PCM_I24_PACKED;
165 break;
166 case AUDIO_FORMAT_PCM_32_BIT:
167 aaudioFormat = AAUDIO_FORMAT_PCM_I32;
168 break;
169 default:
170 aaudioFormat = AAUDIO_FORMAT_INVALID;
171 ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
172 break;
173 }
174 return aaudioFormat;
175 }
176
177 // Make a message string from the condition.
178 #define STATIC_ASSERT(condition) static_assert(condition, #condition)
179
AAudioConvert_usageToInternal(aaudio_usage_t usage)180 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
181 // The public aaudio_content_type_t constants are supposed to have the same
182 // values as the internal audio_content_type_t values.
183 STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
184 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
185 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
186 == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
187 STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
188 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
189 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
190 == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
191 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
192 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
193 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
194 == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
195 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
196 STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
197 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
198 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_EMERGENCY == AUDIO_USAGE_EMERGENCY);
199 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_SAFETY == AUDIO_USAGE_SAFETY);
200 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS == AUDIO_USAGE_VEHICLE_STATUS);
201 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT == AUDIO_USAGE_ANNOUNCEMENT);
202 if (usage == AAUDIO_UNSPECIFIED) {
203 usage = AAUDIO_USAGE_MEDIA;
204 }
205 return (audio_usage_t) usage; // same value
206 }
207
AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType)208 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
209 // The public aaudio_content_type_t constants are supposed to have the same
210 // values as the internal audio_content_type_t values.
211 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
212 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
213 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
214 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
215 if (contentType == AAUDIO_UNSPECIFIED) {
216 contentType = AAUDIO_CONTENT_TYPE_MUSIC;
217 }
218 return (audio_content_type_t) contentType; // same value
219 }
220
AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset)221 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
222 // The public aaudio_input_preset_t constants are supposed to have the same
223 // values as the internal audio_source_t values.
224 STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
225 STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
226 STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
227 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
228 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
229 STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
230 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
231 if (preset == AAUDIO_UNSPECIFIED) {
232 preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
233 }
234 return (audio_source_t) preset; // same value
235 }
236
AAudioConvert_allowCapturePolicyToAudioFlagsMask(aaudio_allowed_capture_policy_t policy,aaudio_spatialization_behavior_t spatializationBehavior,bool isContentSpatialized)237 audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
238 aaudio_allowed_capture_policy_t policy,
239 aaudio_spatialization_behavior_t spatializationBehavior,
240 bool isContentSpatialized) {
241 audio_flags_mask_t flagsMask = AUDIO_FLAG_NONE;
242 switch (policy) {
243 case AAUDIO_UNSPECIFIED:
244 case AAUDIO_ALLOW_CAPTURE_BY_ALL:
245 // flagsMask is not modified
246 break;
247 case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
248 flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_NO_MEDIA_PROJECTION);
249 break;
250 case AAUDIO_ALLOW_CAPTURE_BY_NONE:
251 flagsMask = static_cast<audio_flags_mask_t>(flagsMask |
252 AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE);
253 break;
254 default:
255 ALOGE("%s() 0x%08X unrecognized capture policy", __func__, policy);
256 // flagsMask is not modified
257 }
258
259 switch (spatializationBehavior) {
260 case AAUDIO_UNSPECIFIED:
261 case AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO:
262 // flagsMask is not modified
263 break;
264 case AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER:
265 flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_NEVER_SPATIALIZE);
266 break;
267 default:
268 ALOGE("%s() 0x%08X unrecognized spatialization behavior",
269 __func__, spatializationBehavior);
270 // flagsMask is not modified
271 }
272
273 if (isContentSpatialized) {
274 flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_CONTENT_SPATIALIZED);
275 }
276
277 return flagsMask;
278 }
279
AAudioConvert_privacySensitiveToAudioFlagsMask(bool privacySensitive)280 audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
281 bool privacySensitive) {
282 return privacySensitive ? AUDIO_FLAG_CAPTURE_PRIVATE : AUDIO_FLAG_NONE;
283 }
284
AAudioConvert_aaudioToAndroidChannelLayoutMask(aaudio_channel_mask_t channelMask,bool isInput)285 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelLayoutMask(
286 aaudio_channel_mask_t channelMask, bool isInput) {
287 if (isInput) {
288 switch (channelMask) {
289 case AAUDIO_CHANNEL_MONO:
290 return AUDIO_CHANNEL_IN_MONO;
291 case AAUDIO_CHANNEL_STEREO:
292 return AUDIO_CHANNEL_IN_STEREO;
293 case AAUDIO_CHANNEL_FRONT_BACK:
294 return AUDIO_CHANNEL_IN_FRONT_BACK;
295 case AAUDIO_CHANNEL_2POINT0POINT2:
296 return AUDIO_CHANNEL_IN_2POINT0POINT2;
297 case AAUDIO_CHANNEL_2POINT1POINT2:
298 return AUDIO_CHANNEL_IN_2POINT1POINT2;
299 case AAUDIO_CHANNEL_3POINT0POINT2:
300 return AUDIO_CHANNEL_IN_3POINT0POINT2;
301 case AAUDIO_CHANNEL_3POINT1POINT2:
302 return AUDIO_CHANNEL_IN_3POINT1POINT2;
303 case AAUDIO_CHANNEL_5POINT1:
304 return AUDIO_CHANNEL_IN_5POINT1;
305 default:
306 ALOGE("%s() %#x unrecognized", __func__, channelMask);
307 return AUDIO_CHANNEL_INVALID;
308 }
309 } else {
310 switch (channelMask) {
311 case AAUDIO_CHANNEL_MONO:
312 return AUDIO_CHANNEL_OUT_MONO;
313 case AAUDIO_CHANNEL_STEREO:
314 return AUDIO_CHANNEL_OUT_STEREO;
315 case AAUDIO_CHANNEL_2POINT1:
316 return AUDIO_CHANNEL_OUT_2POINT1;
317 case AAUDIO_CHANNEL_TRI:
318 return AUDIO_CHANNEL_OUT_TRI;
319 case AAUDIO_CHANNEL_TRI_BACK:
320 return AUDIO_CHANNEL_OUT_TRI_BACK;
321 case AAUDIO_CHANNEL_3POINT1:
322 return AUDIO_CHANNEL_OUT_3POINT1;
323 case AAUDIO_CHANNEL_2POINT0POINT2:
324 return AUDIO_CHANNEL_OUT_2POINT0POINT2;
325 case AAUDIO_CHANNEL_2POINT1POINT2:
326 return AUDIO_CHANNEL_OUT_2POINT1POINT2;
327 case AAUDIO_CHANNEL_3POINT0POINT2:
328 return AUDIO_CHANNEL_OUT_3POINT0POINT2;
329 case AAUDIO_CHANNEL_3POINT1POINT2:
330 return AUDIO_CHANNEL_OUT_3POINT1POINT2;
331 case AAUDIO_CHANNEL_QUAD:
332 return AUDIO_CHANNEL_OUT_QUAD;
333 case AAUDIO_CHANNEL_QUAD_SIDE:
334 return AUDIO_CHANNEL_OUT_QUAD_SIDE;
335 case AAUDIO_CHANNEL_SURROUND:
336 return AUDIO_CHANNEL_OUT_SURROUND;
337 case AAUDIO_CHANNEL_PENTA:
338 return AUDIO_CHANNEL_OUT_PENTA;
339 case AAUDIO_CHANNEL_5POINT1:
340 return AUDIO_CHANNEL_OUT_5POINT1;
341 case AAUDIO_CHANNEL_5POINT1_SIDE:
342 return AUDIO_CHANNEL_OUT_5POINT1_SIDE;
343 case AAUDIO_CHANNEL_5POINT1POINT2:
344 return AUDIO_CHANNEL_OUT_5POINT1POINT2;
345 case AAUDIO_CHANNEL_5POINT1POINT4:
346 return AUDIO_CHANNEL_OUT_5POINT1POINT4;
347 case AAUDIO_CHANNEL_6POINT1:
348 return AUDIO_CHANNEL_OUT_6POINT1;
349 case AAUDIO_CHANNEL_7POINT1:
350 return AUDIO_CHANNEL_OUT_7POINT1;
351 case AAUDIO_CHANNEL_7POINT1POINT2:
352 return AUDIO_CHANNEL_OUT_7POINT1POINT2;
353 case AAUDIO_CHANNEL_7POINT1POINT4:
354 return AUDIO_CHANNEL_OUT_7POINT1POINT4;
355 // TODO: add 9point1point4 and 9point1point6 when they are added in audio-hal-enums.h
356 // case AAUDIO_CHANNEL_9POINT1POINT4:
357 // return AUDIO_CHANNEL_OUT_9POINT1POINT4;
358 // case AAUDIO_CHANNEL_9POINT1POINT6:
359 // return AUDIO_CHANNEL_OUT_9POINT1POINT6;
360 default:
361 ALOGE("%s() %#x unrecognized", __func__, channelMask);
362 return AUDIO_CHANNEL_INVALID;
363 }
364 }
365 }
366
AAudioConvert_androidToAAudioChannelLayoutMask(audio_channel_mask_t channelMask,bool isInput)367 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelLayoutMask(
368 audio_channel_mask_t channelMask, bool isInput) {
369 if (isInput) {
370 switch (channelMask) {
371 case AUDIO_CHANNEL_IN_MONO:
372 return AAUDIO_CHANNEL_MONO;
373 case AUDIO_CHANNEL_IN_STEREO:
374 return AAUDIO_CHANNEL_STEREO;
375 case AUDIO_CHANNEL_IN_FRONT_BACK:
376 return AAUDIO_CHANNEL_FRONT_BACK;
377 case AUDIO_CHANNEL_IN_2POINT0POINT2:
378 return AAUDIO_CHANNEL_2POINT0POINT2;
379 case AUDIO_CHANNEL_IN_2POINT1POINT2:
380 return AAUDIO_CHANNEL_2POINT1POINT2;
381 case AUDIO_CHANNEL_IN_3POINT0POINT2:
382 return AAUDIO_CHANNEL_3POINT0POINT2;
383 case AUDIO_CHANNEL_IN_3POINT1POINT2:
384 return AAUDIO_CHANNEL_3POINT1POINT2;
385 case AUDIO_CHANNEL_IN_5POINT1:
386 return AAUDIO_CHANNEL_5POINT1;
387 default:
388 ALOGE("%s() %#x unrecognized", __func__, channelMask);
389 return AAUDIO_CHANNEL_INVALID;
390 }
391 } else {
392 switch (channelMask) {
393 case AUDIO_CHANNEL_OUT_MONO:
394 return AAUDIO_CHANNEL_MONO;
395 case AUDIO_CHANNEL_OUT_STEREO:
396 return AAUDIO_CHANNEL_STEREO;
397 case AUDIO_CHANNEL_OUT_2POINT1:
398 return AAUDIO_CHANNEL_2POINT1;
399 case AUDIO_CHANNEL_OUT_TRI:
400 return AAUDIO_CHANNEL_TRI;
401 case AUDIO_CHANNEL_OUT_TRI_BACK:
402 return AAUDIO_CHANNEL_TRI_BACK;
403 case AUDIO_CHANNEL_OUT_3POINT1:
404 return AAUDIO_CHANNEL_3POINT1;
405 case AUDIO_CHANNEL_OUT_2POINT0POINT2:
406 return AAUDIO_CHANNEL_2POINT0POINT2;
407 case AUDIO_CHANNEL_OUT_2POINT1POINT2:
408 return AAUDIO_CHANNEL_2POINT1POINT2;
409 case AUDIO_CHANNEL_OUT_3POINT0POINT2:
410 return AAUDIO_CHANNEL_3POINT0POINT2;
411 case AUDIO_CHANNEL_OUT_3POINT1POINT2:
412 return AAUDIO_CHANNEL_3POINT1POINT2;
413 case AUDIO_CHANNEL_OUT_QUAD:
414 return AAUDIO_CHANNEL_QUAD;
415 case AUDIO_CHANNEL_OUT_QUAD_SIDE:
416 return AAUDIO_CHANNEL_QUAD_SIDE;
417 case AUDIO_CHANNEL_OUT_SURROUND:
418 return AAUDIO_CHANNEL_SURROUND;
419 case AUDIO_CHANNEL_OUT_PENTA:
420 return AAUDIO_CHANNEL_PENTA;
421 case AUDIO_CHANNEL_OUT_5POINT1:
422 return AAUDIO_CHANNEL_5POINT1;
423 case AUDIO_CHANNEL_OUT_5POINT1_SIDE:
424 return AAUDIO_CHANNEL_5POINT1_SIDE;
425 case AUDIO_CHANNEL_OUT_5POINT1POINT2:
426 return AAUDIO_CHANNEL_5POINT1POINT2;
427 case AUDIO_CHANNEL_OUT_5POINT1POINT4:
428 return AAUDIO_CHANNEL_5POINT1POINT4;
429 case AUDIO_CHANNEL_OUT_6POINT1:
430 return AAUDIO_CHANNEL_6POINT1;
431 case AUDIO_CHANNEL_OUT_7POINT1:
432 return AAUDIO_CHANNEL_7POINT1;
433 case AUDIO_CHANNEL_OUT_7POINT1POINT2:
434 return AAUDIO_CHANNEL_7POINT1POINT2;
435 case AUDIO_CHANNEL_OUT_7POINT1POINT4:
436 return AAUDIO_CHANNEL_7POINT1POINT4;
437 // TODO: add 9point1point4 and 9point1point6 when they are added in audio-hal-enums.h
438 // case AUDIO_CHANNEL_OUT_9POINT1POINT4:
439 // return AAUDIO_CHANNEL_9POINT1POINT4;
440 // case AUDIO_CHANNEL_OUT_9POINT1POINT6:
441 // return AAUDIO_CHANNEL_9POINT1POINT6;
442 default:
443 ALOGE("%s() %#x unrecognized", __func__, channelMask);
444 return AAUDIO_CHANNEL_INVALID;
445 }
446 }
447 }
448
AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask)449 int32_t AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask) {
450 return __builtin_popcount(channelMask & ~AAUDIO_CHANNEL_BIT_INDEX);
451 }
452
AAudioConvert_channelCountToMask(int32_t channelCount)453 aaudio_channel_mask_t AAudioConvert_channelCountToMask(int32_t channelCount) {
454 if (channelCount < 0 || channelCount > AUDIO_CHANNEL_COUNT_MAX) {
455 return AAUDIO_CHANNEL_INVALID;
456 }
457
458 if (channelCount == 0) {
459 return AAUDIO_UNSPECIFIED;
460 }
461
462 // Return index mask if the channel count is greater than 2.
463 return AAUDIO_CHANNEL_BIT_INDEX | ((1 << channelCount) - 1);
464 }
465
AAudioConvert_androidToAAudioChannelIndexMask(audio_channel_mask_t channelMask)466 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelIndexMask(
467 audio_channel_mask_t channelMask) {
468 if (audio_channel_mask_get_representation(channelMask) != AUDIO_CHANNEL_REPRESENTATION_INDEX) {
469 ALOGE("%s() %#x not an index mask", __func__, channelMask);
470 return AAUDIO_CHANNEL_INVALID;
471 }
472 return (channelMask & ~AUDIO_CHANNEL_INDEX_HDR) | AAUDIO_CHANNEL_BIT_INDEX;
473 }
474
AAudioConvert_aaudioToAndroidChannelIndexMask(aaudio_channel_mask_t channelMask)475 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelIndexMask(
476 aaudio_channel_mask_t channelMask) {
477 if (!AAudio_isChannelIndexMask(channelMask)) {
478 ALOGE("%s() %#x not an index mask", __func__, channelMask);
479 return AUDIO_CHANNEL_INVALID;
480 }
481 return audio_channel_mask_for_index_assignment_from_count(
482 AAudioConvert_channelMaskToCount(channelMask));
483 }
484
AAudioConvert_androidToAAudioChannelMask(audio_channel_mask_t channelMask,bool isInput,bool indexMaskRequired)485 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelMask(
486 audio_channel_mask_t channelMask, bool isInput, bool indexMaskRequired) {
487 if (audio_channel_mask_get_representation(channelMask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
488 return AAudioConvert_androidToAAudioChannelIndexMask(channelMask);
489 }
490 if (indexMaskRequired) {
491 // Require index mask, `channelMask` here is a position mask.
492 const int channelCount = isInput ? audio_channel_count_from_in_mask(channelMask)
493 : audio_channel_count_from_out_mask(channelMask);
494 return AAudioConvert_channelCountToMask(channelCount);
495 }
496 return AAudioConvert_androidToAAudioChannelLayoutMask(channelMask, isInput);
497 }
498
AAudioConvert_aaudioToAndroidChannelMask(aaudio_channel_mask_t channelMask,bool isInput)499 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelMask(
500 aaudio_channel_mask_t channelMask, bool isInput) {
501 return AAudio_isChannelIndexMask(channelMask)
502 ? AAudioConvert_aaudioToAndroidChannelIndexMask(channelMask)
503 : AAudioConvert_aaudioToAndroidChannelLayoutMask(channelMask, isInput);
504 }
505
AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask)506 bool AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask) {
507 return (channelMask & AAUDIO_CHANNEL_BIT_INDEX) == AAUDIO_CHANNEL_BIT_INDEX;
508 }
509
AAudio_getChannelMaskForOpen(aaudio_channel_mask_t channelMask,int32_t samplesPerFrame,bool isInput)510 audio_channel_mask_t AAudio_getChannelMaskForOpen(
511 aaudio_channel_mask_t channelMask, int32_t samplesPerFrame, bool isInput) {
512 if (channelMask != AAUDIO_UNSPECIFIED) {
513 if (AAudio_isChannelIndexMask(channelMask) && samplesPerFrame <= 2) {
514 // When it is index mask and the count is less than 3, use position mask
515 // instead of index mask for opening a stream. This may need to be revisited
516 // when making channel index mask public.
517 return isInput ? audio_channel_in_mask_from_count(samplesPerFrame)
518 : audio_channel_out_mask_from_count(samplesPerFrame);
519 }
520 return AAudioConvert_aaudioToAndroidChannelMask(channelMask, isInput);
521 }
522
523 // Return stereo when unspecified.
524 return isInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
525 }
526
AAudioConvert_framesToBytes(int32_t numFrames,int32_t bytesPerFrame,int32_t * sizeInBytes)527 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
528 int32_t bytesPerFrame,
529 int32_t *sizeInBytes) {
530 *sizeInBytes = 0;
531
532 if (numFrames < 0 || bytesPerFrame < 0) {
533 ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
534 return AAUDIO_ERROR_OUT_OF_RANGE;
535 }
536
537 // Prevent numeric overflow.
538 if (numFrames > (INT32_MAX / bytesPerFrame)) {
539 ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
540 return AAUDIO_ERROR_OUT_OF_RANGE;
541 }
542
543 *sizeInBytes = numFrames * bytesPerFrame;
544 return AAUDIO_OK;
545 }
546
AAudioProperty_getWakeupDelayMicros()547 int32_t AAudioProperty_getWakeupDelayMicros() {
548 const int32_t minMicros = 0; // arbitrary
549 const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter
550 const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500
551 int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros);
552 if (prop < minMicros) {
553 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros);
554 prop = minMicros;
555 } else if (prop > maxMicros) {
556 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros);
557 prop = maxMicros;
558 }
559 return prop;
560 }
561
AAudioProperty_getMinimumSleepMicros()562 int32_t AAudioProperty_getMinimumSleepMicros() {
563 const int32_t minMicros = 1; // arbitrary
564 // Higher values can increase latency for moderate workloads.
565 // Short values can cause the CPU to short cycle if there is a bug in
566 // calculating the wakeup times.
567 const int32_t defaultMicros = 100; // arbitrary
568 const int32_t maxMicros = 200; // arbitrary
569 int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
570 if (prop < minMicros) {
571 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros);
572 prop = minMicros;
573 } else if (prop > maxMicros) {
574 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros);
575 prop = maxMicros;
576 }
577 return prop;
578 }
579
AAudioProperty_getMMapOffsetMicros(const char * functionName,const char * propertyName)580 static int32_t AAudioProperty_getMMapOffsetMicros(const char *functionName,
581 const char *propertyName) {
582 const int32_t minMicros = -20000; // arbitrary
583 const int32_t defaultMicros = 0; // arbitrary
584 const int32_t maxMicros = 20000; // arbitrary
585 int32_t prop = property_get_int32(propertyName, defaultMicros);
586 if (prop < minMicros) {
587 ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
588 prop = minMicros;
589 } else if (prop > maxMicros) {
590 ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
591 prop = maxMicros;
592 }
593 return prop;
594 }
595
AAudioProperty_getInputMMapOffsetMicros()596 int32_t AAudioProperty_getInputMMapOffsetMicros() {
597 return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC);
598 }
599
AAudioProperty_getOutputMMapOffsetMicros()600 int32_t AAudioProperty_getOutputMMapOffsetMicros() {
601 return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC);
602 }
603
AAudioProperty_getLogMask()604 int32_t AAudioProperty_getLogMask() {
605 return property_get_int32(AAUDIO_PROP_LOG_MASK, 0);
606 }
607
AAudio_isFlushAllowed(aaudio_stream_state_t state)608 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
609 aaudio_result_t result = AAUDIO_OK;
610 switch (state) {
611 // Proceed with flushing.
612 case AAUDIO_STREAM_STATE_OPEN:
613 case AAUDIO_STREAM_STATE_PAUSED:
614 case AAUDIO_STREAM_STATE_STOPPED:
615 case AAUDIO_STREAM_STATE_FLUSHED:
616 break;
617
618 // Transition from one inactive state to another.
619 case AAUDIO_STREAM_STATE_STARTING:
620 case AAUDIO_STREAM_STATE_STARTED:
621 case AAUDIO_STREAM_STATE_STOPPING:
622 case AAUDIO_STREAM_STATE_PAUSING:
623 case AAUDIO_STREAM_STATE_FLUSHING:
624 case AAUDIO_STREAM_STATE_CLOSING:
625 case AAUDIO_STREAM_STATE_CLOSED:
626 case AAUDIO_STREAM_STATE_DISCONNECTED:
627 default:
628 ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
629 aaudio::AudioGlobal_convertStreamStateToText(state));
630 result = AAUDIO_ERROR_INVALID_STATE;
631 break;
632 }
633 return result;
634 }
635