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