xref: /aosp_15_r20/frameworks/av/media/libaaudio/src/utility/AAudioUtilities.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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     case AAUDIO_FORMAT_MP3:
151         androidFormat = AUDIO_FORMAT_MP3;
152         break;
153     case AAUDIO_FORMAT_AAC_LC:
154         androidFormat = AUDIO_FORMAT_AAC_LC;
155         break;
156     case AAUDIO_FORMAT_AAC_HE_V1:
157         androidFormat = AUDIO_FORMAT_AAC_HE_V1;
158         break;
159     case AAUDIO_FORMAT_AAC_HE_V2:
160         androidFormat = AUDIO_FORMAT_AAC_HE_V2;
161         break;
162     case AAUDIO_FORMAT_AAC_ELD:
163         androidFormat = AUDIO_FORMAT_AAC_ELD;
164         break;
165     case AAUDIO_FORMAT_AAC_XHE:
166         androidFormat = AUDIO_FORMAT_AAC_XHE;
167         break;
168     case AAUDIO_FORMAT_OPUS:
169         androidFormat = AUDIO_FORMAT_OPUS;
170         break;
171     default:
172         androidFormat = AUDIO_FORMAT_INVALID;
173         ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
174         break;
175     }
176     return androidFormat;
177 }
178 
AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat)179 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
180     aaudio_format_t aaudioFormat;
181     switch (androidFormat) {
182     case AUDIO_FORMAT_DEFAULT:
183         aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
184         break;
185     case AUDIO_FORMAT_PCM_16_BIT:
186         aaudioFormat = AAUDIO_FORMAT_PCM_I16;
187         break;
188     case AUDIO_FORMAT_PCM_FLOAT:
189         aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
190         break;
191     case AUDIO_FORMAT_PCM_24_BIT_PACKED:
192         aaudioFormat = AAUDIO_FORMAT_PCM_I24_PACKED;
193         break;
194     case AUDIO_FORMAT_PCM_32_BIT:
195         aaudioFormat = AAUDIO_FORMAT_PCM_I32;
196         break;
197     case AUDIO_FORMAT_IEC61937:
198         aaudioFormat = AAUDIO_FORMAT_IEC61937;
199         break;
200     case AUDIO_FORMAT_MP3:
201         aaudioFormat = AAUDIO_FORMAT_MP3;
202         break;
203     case AUDIO_FORMAT_AAC_LC:
204         aaudioFormat = AAUDIO_FORMAT_AAC_LC;
205         break;
206     case AUDIO_FORMAT_AAC_HE_V1:
207         aaudioFormat = AAUDIO_FORMAT_AAC_HE_V1;
208         break;
209     case AUDIO_FORMAT_AAC_HE_V2:
210         aaudioFormat = AAUDIO_FORMAT_AAC_HE_V2;
211         break;
212     case AUDIO_FORMAT_AAC_ELD:
213         aaudioFormat = AAUDIO_FORMAT_AAC_ELD;
214         break;
215     case AUDIO_FORMAT_AAC_XHE:
216         aaudioFormat = AAUDIO_FORMAT_AAC_XHE;
217         break;
218     case AUDIO_FORMAT_OPUS:
219         aaudioFormat = AAUDIO_FORMAT_OPUS;
220         break;
221     default:
222         aaudioFormat = AAUDIO_FORMAT_INVALID;
223         ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
224         break;
225     }
226     return aaudioFormat;
227 }
228 
AAudioConvert_androidToNearestAAudioDataFormat(audio_format_t androidFormat)229 aaudio_format_t AAudioConvert_androidToNearestAAudioDataFormat(audio_format_t androidFormat) {
230     // Special case AUDIO_FORMAT_PCM_8_24_BIT because this function should be used to find the
231     // resolution of the data format. Setting AUDIO_FORMAT_PCM_8_24_BIT directly is not available
232     // from AAudio but hardware may use AUDIO_FORMAT_PCM_8_24_BIT under the hood.
233     if (androidFormat == AUDIO_FORMAT_PCM_8_24_BIT) {
234         ALOGD("%s() converting 8.24 to 24 bit packed", __func__);
235         return AAUDIO_FORMAT_PCM_I24_PACKED;
236     }
237     return AAudioConvert_androidToAAudioDataFormat(androidFormat);
238 }
239 
240 // Make a message string from the condition.
241 #define STATIC_ASSERT(condition) static_assert(condition, #condition)
242 
AAudioConvert_usageToInternal(aaudio_usage_t usage)243 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
244     // The public aaudio_content_type_t constants are supposed to have the same
245     // values as the internal audio_content_type_t values.
246     STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
247     STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
248     STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
249                   == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
250     STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
251     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
252     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
253                   == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
254     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
255     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
256     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
257                   == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
258     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
259     STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
260     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
261     STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_EMERGENCY == AUDIO_USAGE_EMERGENCY);
262     STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_SAFETY == AUDIO_USAGE_SAFETY);
263     STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS == AUDIO_USAGE_VEHICLE_STATUS);
264     STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT == AUDIO_USAGE_ANNOUNCEMENT);
265     if (usage == AAUDIO_UNSPECIFIED) {
266         usage = AAUDIO_USAGE_MEDIA;
267     }
268     return (audio_usage_t) usage; // same value
269 }
270 
AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType)271 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
272     // The public aaudio_content_type_t constants are supposed to have the same
273     // values as the internal audio_content_type_t values.
274     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
275     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
276     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
277     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
278     if (contentType == AAUDIO_UNSPECIFIED) {
279         contentType = AAUDIO_CONTENT_TYPE_MUSIC;
280     }
281     return (audio_content_type_t) contentType; // same value
282 }
283 
AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset)284 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
285     // The public aaudio_input_preset_t constants are supposed to have the same
286     // values as the internal audio_source_t values.
287     STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
288     STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
289     STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
290     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
291     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
292     STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
293     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
294     if (preset == AAUDIO_UNSPECIFIED) {
295         preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
296     }
297     return (audio_source_t) preset; // same value
298 }
299 
AAudio_computeAudioFlagsMask(aaudio_allowed_capture_policy_t policy,aaudio_spatialization_behavior_t spatializationBehavior,bool isContentSpatialized,audio_output_flags_t outputFlags)300 audio_flags_mask_t AAudio_computeAudioFlagsMask(
301         aaudio_allowed_capture_policy_t policy,
302         aaudio_spatialization_behavior_t spatializationBehavior,
303         bool isContentSpatialized,
304         audio_output_flags_t outputFlags) {
305     audio_flags_mask_t flagsMask = AUDIO_FLAG_NONE;
306     switch (policy) {
307         case AAUDIO_UNSPECIFIED:
308         case AAUDIO_ALLOW_CAPTURE_BY_ALL:
309             // flagsMask is not modified
310             break;
311         case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
312             flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_NO_MEDIA_PROJECTION);
313             break;
314         case AAUDIO_ALLOW_CAPTURE_BY_NONE:
315             flagsMask = static_cast<audio_flags_mask_t>(flagsMask |
316                     AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE);
317             break;
318         default:
319             ALOGE("%s() 0x%08X unrecognized capture policy", __func__, policy);
320             // flagsMask is not modified
321     }
322 
323     switch (spatializationBehavior) {
324         case AAUDIO_UNSPECIFIED:
325         case AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO:
326             // flagsMask is not modified
327             break;
328         case AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER:
329             flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_NEVER_SPATIALIZE);
330             break;
331         default:
332             ALOGE("%s() 0x%08X unrecognized spatialization behavior",
333                   __func__, spatializationBehavior);
334             // flagsMask is not modified
335     }
336 
337     if (isContentSpatialized) {
338         flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_CONTENT_SPATIALIZED);
339     }
340 
341     if ((outputFlags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
342         flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_HW_AV_SYNC);
343     }
344     if ((outputFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
345         flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_LOW_LATENCY);
346     } else if ((outputFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
347         flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_DEEP_BUFFER);
348     }
349 
350     return flagsMask;
351 }
352 
AAudioConvert_privacySensitiveToAudioFlagsMask(bool privacySensitive)353 audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
354         bool privacySensitive) {
355     return privacySensitive ? AUDIO_FLAG_CAPTURE_PRIVATE : AUDIO_FLAG_NONE;
356 }
357 
AAudioConvert_aaudioToAndroidChannelLayoutMask(aaudio_channel_mask_t channelMask,bool isInput)358 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelLayoutMask(
359         aaudio_channel_mask_t channelMask, bool isInput) {
360     if (isInput) {
361         switch (channelMask) {
362             case AAUDIO_CHANNEL_MONO:
363                 return AUDIO_CHANNEL_IN_MONO;
364             case AAUDIO_CHANNEL_STEREO:
365                 return AUDIO_CHANNEL_IN_STEREO;
366             case AAUDIO_CHANNEL_FRONT_BACK:
367                 return AUDIO_CHANNEL_IN_FRONT_BACK;
368             case AAUDIO_CHANNEL_2POINT0POINT2:
369                 return AUDIO_CHANNEL_IN_2POINT0POINT2;
370             case AAUDIO_CHANNEL_2POINT1POINT2:
371                 return AUDIO_CHANNEL_IN_2POINT1POINT2;
372             case AAUDIO_CHANNEL_3POINT0POINT2:
373                 return AUDIO_CHANNEL_IN_3POINT0POINT2;
374             case AAUDIO_CHANNEL_3POINT1POINT2:
375                 return AUDIO_CHANNEL_IN_3POINT1POINT2;
376             case AAUDIO_CHANNEL_5POINT1:
377                 return AUDIO_CHANNEL_IN_5POINT1;
378             default:
379                 ALOGE("%s() %#x unrecognized", __func__, channelMask);
380                 return AUDIO_CHANNEL_INVALID;
381         }
382     } else {
383         switch (channelMask) {
384             case AAUDIO_CHANNEL_MONO:
385                 return AUDIO_CHANNEL_OUT_MONO;
386             case AAUDIO_CHANNEL_STEREO:
387                 return AUDIO_CHANNEL_OUT_STEREO;
388             case AAUDIO_CHANNEL_2POINT1:
389                 return AUDIO_CHANNEL_OUT_2POINT1;
390             case AAUDIO_CHANNEL_TRI:
391                 return AUDIO_CHANNEL_OUT_TRI;
392             case AAUDIO_CHANNEL_TRI_BACK:
393                 return AUDIO_CHANNEL_OUT_TRI_BACK;
394             case AAUDIO_CHANNEL_3POINT1:
395                 return AUDIO_CHANNEL_OUT_3POINT1;
396             case AAUDIO_CHANNEL_2POINT0POINT2:
397                 return AUDIO_CHANNEL_OUT_2POINT0POINT2;
398             case AAUDIO_CHANNEL_2POINT1POINT2:
399                 return AUDIO_CHANNEL_OUT_2POINT1POINT2;
400             case AAUDIO_CHANNEL_3POINT0POINT2:
401                 return AUDIO_CHANNEL_OUT_3POINT0POINT2;
402             case AAUDIO_CHANNEL_3POINT1POINT2:
403                 return AUDIO_CHANNEL_OUT_3POINT1POINT2;
404             case AAUDIO_CHANNEL_QUAD:
405                 return AUDIO_CHANNEL_OUT_QUAD;
406             case AAUDIO_CHANNEL_QUAD_SIDE:
407                 return AUDIO_CHANNEL_OUT_QUAD_SIDE;
408             case AAUDIO_CHANNEL_SURROUND:
409                 return AUDIO_CHANNEL_OUT_SURROUND;
410             case AAUDIO_CHANNEL_PENTA:
411                 return AUDIO_CHANNEL_OUT_PENTA;
412             case AAUDIO_CHANNEL_5POINT1:
413                 return AUDIO_CHANNEL_OUT_5POINT1;
414             case AAUDIO_CHANNEL_5POINT1_SIDE:
415                 return AUDIO_CHANNEL_OUT_5POINT1_SIDE;
416             case AAUDIO_CHANNEL_5POINT1POINT2:
417                 return AUDIO_CHANNEL_OUT_5POINT1POINT2;
418             case AAUDIO_CHANNEL_5POINT1POINT4:
419                 return AUDIO_CHANNEL_OUT_5POINT1POINT4;
420             case AAUDIO_CHANNEL_6POINT1:
421                 return AUDIO_CHANNEL_OUT_6POINT1;
422             case AAUDIO_CHANNEL_7POINT1:
423                 return AUDIO_CHANNEL_OUT_7POINT1;
424             case AAUDIO_CHANNEL_7POINT1POINT2:
425                 return AUDIO_CHANNEL_OUT_7POINT1POINT2;
426             case AAUDIO_CHANNEL_7POINT1POINT4:
427                 return AUDIO_CHANNEL_OUT_7POINT1POINT4;
428             case AAUDIO_CHANNEL_9POINT1POINT4:
429                 return AUDIO_CHANNEL_OUT_9POINT1POINT4;
430             case AAUDIO_CHANNEL_9POINT1POINT6:
431                 return AUDIO_CHANNEL_OUT_9POINT1POINT6;
432             default:
433                 ALOGE("%s() %#x unrecognized", __func__, channelMask);
434                 return AUDIO_CHANNEL_INVALID;
435         }
436     }
437 }
438 
AAudioConvert_androidToAAudioChannelLayoutMask(audio_channel_mask_t channelMask,bool isInput)439 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelLayoutMask(
440         audio_channel_mask_t channelMask, bool isInput) {
441     if (isInput) {
442         switch (channelMask) {
443             case AUDIO_CHANNEL_IN_MONO:
444                 return AAUDIO_CHANNEL_MONO;
445             case AUDIO_CHANNEL_IN_STEREO:
446                 return AAUDIO_CHANNEL_STEREO;
447             case AUDIO_CHANNEL_IN_FRONT_BACK:
448                 return AAUDIO_CHANNEL_FRONT_BACK;
449             case AUDIO_CHANNEL_IN_2POINT0POINT2:
450                 return AAUDIO_CHANNEL_2POINT0POINT2;
451             case AUDIO_CHANNEL_IN_2POINT1POINT2:
452                 return AAUDIO_CHANNEL_2POINT1POINT2;
453             case AUDIO_CHANNEL_IN_3POINT0POINT2:
454                 return AAUDIO_CHANNEL_3POINT0POINT2;
455             case AUDIO_CHANNEL_IN_3POINT1POINT2:
456                 return AAUDIO_CHANNEL_3POINT1POINT2;
457             case AUDIO_CHANNEL_IN_5POINT1:
458                 return AAUDIO_CHANNEL_5POINT1;
459             default:
460                 ALOGE("%s() %#x unrecognized", __func__, channelMask);
461                 return AAUDIO_CHANNEL_INVALID;
462         }
463     } else {
464         switch (channelMask) {
465             case AUDIO_CHANNEL_OUT_MONO:
466                 return AAUDIO_CHANNEL_MONO;
467             case AUDIO_CHANNEL_OUT_STEREO:
468                 return AAUDIO_CHANNEL_STEREO;
469             case AUDIO_CHANNEL_OUT_2POINT1:
470                 return AAUDIO_CHANNEL_2POINT1;
471             case AUDIO_CHANNEL_OUT_TRI:
472                 return AAUDIO_CHANNEL_TRI;
473             case AUDIO_CHANNEL_OUT_TRI_BACK:
474                 return AAUDIO_CHANNEL_TRI_BACK;
475             case AUDIO_CHANNEL_OUT_3POINT1:
476                 return AAUDIO_CHANNEL_3POINT1;
477             case AUDIO_CHANNEL_OUT_2POINT0POINT2:
478                 return AAUDIO_CHANNEL_2POINT0POINT2;
479             case AUDIO_CHANNEL_OUT_2POINT1POINT2:
480                 return AAUDIO_CHANNEL_2POINT1POINT2;
481             case AUDIO_CHANNEL_OUT_3POINT0POINT2:
482                 return AAUDIO_CHANNEL_3POINT0POINT2;
483             case AUDIO_CHANNEL_OUT_3POINT1POINT2:
484                 return AAUDIO_CHANNEL_3POINT1POINT2;
485             case AUDIO_CHANNEL_OUT_QUAD:
486                 return AAUDIO_CHANNEL_QUAD;
487             case AUDIO_CHANNEL_OUT_QUAD_SIDE:
488                 return AAUDIO_CHANNEL_QUAD_SIDE;
489             case AUDIO_CHANNEL_OUT_SURROUND:
490                 return AAUDIO_CHANNEL_SURROUND;
491             case AUDIO_CHANNEL_OUT_PENTA:
492                 return AAUDIO_CHANNEL_PENTA;
493             case AUDIO_CHANNEL_OUT_5POINT1:
494                 return AAUDIO_CHANNEL_5POINT1;
495             case AUDIO_CHANNEL_OUT_5POINT1_SIDE:
496                 return AAUDIO_CHANNEL_5POINT1_SIDE;
497             case AUDIO_CHANNEL_OUT_5POINT1POINT2:
498                 return AAUDIO_CHANNEL_5POINT1POINT2;
499             case AUDIO_CHANNEL_OUT_5POINT1POINT4:
500                 return AAUDIO_CHANNEL_5POINT1POINT4;
501             case AUDIO_CHANNEL_OUT_6POINT1:
502                 return AAUDIO_CHANNEL_6POINT1;
503             case AUDIO_CHANNEL_OUT_7POINT1:
504                 return AAUDIO_CHANNEL_7POINT1;
505             case AUDIO_CHANNEL_OUT_7POINT1POINT2:
506                 return AAUDIO_CHANNEL_7POINT1POINT2;
507             case AUDIO_CHANNEL_OUT_7POINT1POINT4:
508                 return AAUDIO_CHANNEL_7POINT1POINT4;
509             case AUDIO_CHANNEL_OUT_9POINT1POINT4:
510                 return AAUDIO_CHANNEL_9POINT1POINT4;
511             case AUDIO_CHANNEL_OUT_9POINT1POINT6:
512                 return AAUDIO_CHANNEL_9POINT1POINT6;
513             default:
514                 ALOGE("%s() %#x unrecognized", __func__, channelMask);
515                 return AAUDIO_CHANNEL_INVALID;
516         }
517     }
518 }
519 
AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask)520 int32_t AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask) {
521     return __builtin_popcount(channelMask & ~AAUDIO_CHANNEL_BIT_INDEX);
522 }
523 
AAudioConvert_channelCountToMask(int32_t channelCount)524 aaudio_channel_mask_t AAudioConvert_channelCountToMask(int32_t channelCount) {
525     if (channelCount < 0 || channelCount > AUDIO_CHANNEL_COUNT_MAX) {
526         return AAUDIO_CHANNEL_INVALID;
527     }
528 
529     if (channelCount == 0) {
530         return AAUDIO_UNSPECIFIED;
531     }
532 
533     // Return index mask if the channel count is greater than 2.
534     return AAUDIO_CHANNEL_BIT_INDEX | ((1 << channelCount) - 1);
535 }
536 
AAudioConvert_androidToAAudioChannelIndexMask(audio_channel_mask_t channelMask)537 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelIndexMask(
538         audio_channel_mask_t channelMask) {
539     if (audio_channel_mask_get_representation(channelMask) != AUDIO_CHANNEL_REPRESENTATION_INDEX) {
540         ALOGE("%s() %#x not an index mask", __func__, channelMask);
541         return AAUDIO_CHANNEL_INVALID;
542     }
543     return (channelMask & ~AUDIO_CHANNEL_INDEX_HDR) | AAUDIO_CHANNEL_BIT_INDEX;
544 }
545 
AAudioConvert_aaudioToAndroidChannelIndexMask(aaudio_channel_mask_t channelMask)546 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelIndexMask(
547         aaudio_channel_mask_t channelMask) {
548     if (!AAudio_isChannelIndexMask(channelMask)) {
549         ALOGE("%s() %#x not an index mask", __func__, channelMask);
550         return AUDIO_CHANNEL_INVALID;
551     }
552     return audio_channel_mask_for_index_assignment_from_count(
553             AAudioConvert_channelMaskToCount(channelMask));
554 }
555 
AAudioConvert_androidToAAudioChannelMask(audio_channel_mask_t channelMask,bool isInput,bool indexMaskRequired)556 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelMask(
557         audio_channel_mask_t channelMask, bool isInput, bool indexMaskRequired) {
558     if (audio_channel_mask_get_representation(channelMask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
559         return AAudioConvert_androidToAAudioChannelIndexMask(channelMask);
560     }
561     if (indexMaskRequired) {
562         // Require index mask, `channelMask` here is a position mask.
563         const int channelCount = isInput ? audio_channel_count_from_in_mask(channelMask)
564                                          : audio_channel_count_from_out_mask(channelMask);
565         return AAudioConvert_channelCountToMask(channelCount);
566     }
567     return AAudioConvert_androidToAAudioChannelLayoutMask(channelMask, isInput);
568 }
569 
AAudioConvert_aaudioToAndroidChannelMask(aaudio_channel_mask_t channelMask,bool isInput)570 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelMask(
571         aaudio_channel_mask_t channelMask, bool isInput) {
572     return AAudio_isChannelIndexMask(channelMask)
573             ? AAudioConvert_aaudioToAndroidChannelIndexMask(channelMask)
574             : AAudioConvert_aaudioToAndroidChannelLayoutMask(channelMask, isInput);
575 }
576 
AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask)577 bool AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask) {
578     return (channelMask & AAUDIO_CHANNEL_BIT_INDEX) == AAUDIO_CHANNEL_BIT_INDEX;
579 }
580 
AAudio_getChannelMaskForOpen(aaudio_channel_mask_t channelMask,int32_t samplesPerFrame,bool isInput)581 audio_channel_mask_t AAudio_getChannelMaskForOpen(
582         aaudio_channel_mask_t channelMask, int32_t samplesPerFrame, bool isInput) {
583     if (channelMask != AAUDIO_UNSPECIFIED) {
584         if (AAudio_isChannelIndexMask(channelMask) && samplesPerFrame <= 2) {
585             // When it is index mask and the count is less than 3, use position mask
586             // instead of index mask for opening a stream. This may need to be revisited
587             // when making channel index mask public.
588             return isInput ? audio_channel_in_mask_from_count(samplesPerFrame)
589                            : audio_channel_out_mask_from_count(samplesPerFrame);
590         }
591         return AAudioConvert_aaudioToAndroidChannelMask(channelMask, isInput);
592     }
593 
594     // Return stereo when unspecified.
595     return isInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
596 }
597 
AAudioConvert_framesToBytes(int32_t numFrames,int32_t bytesPerFrame,int32_t * sizeInBytes)598 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
599                                     int32_t bytesPerFrame,
600                                     int32_t *sizeInBytes) {
601     *sizeInBytes = 0;
602 
603     if (numFrames < 0 || bytesPerFrame < 0) {
604         ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
605         return AAUDIO_ERROR_OUT_OF_RANGE;
606     }
607 
608     // Prevent numeric overflow.
609     if (numFrames > (INT32_MAX / bytesPerFrame)) {
610         ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
611         return AAUDIO_ERROR_OUT_OF_RANGE;
612     }
613 
614     *sizeInBytes = numFrames * bytesPerFrame;
615     return AAUDIO_OK;
616 }
617 
AAudioProperty_getWakeupDelayMicros()618 int32_t AAudioProperty_getWakeupDelayMicros() {
619     const int32_t minMicros = 0; // arbitrary
620     const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter
621     const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500
622     int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros);
623     if (prop < minMicros) {
624         ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros);
625         prop = minMicros;
626     } else if (prop > maxMicros) {
627         ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros);
628         prop = maxMicros;
629     }
630     return prop;
631 }
632 
AAudioProperty_getMinimumSleepMicros()633 int32_t AAudioProperty_getMinimumSleepMicros() {
634     const int32_t minMicros = 1; // arbitrary
635     // Higher values can increase latency for moderate workloads.
636     // Short values can cause the CPU to short cycle if there is a bug in
637     // calculating the wakeup times.
638     const int32_t defaultMicros = 100; // arbitrary
639     const int32_t maxMicros = 200; // arbitrary
640     int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
641     if (prop < minMicros) {
642         ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros);
643         prop = minMicros;
644     } else if (prop > maxMicros) {
645         ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros);
646         prop = maxMicros;
647     }
648     return prop;
649 }
650 
AAudioProperty_getMMapOffsetMicros(const char * functionName,const char * propertyName)651 static int32_t AAudioProperty_getMMapOffsetMicros(const char *functionName,
652         const char *propertyName) {
653     const int32_t minMicros = -20000; // arbitrary
654     const int32_t defaultMicros = 0;  // arbitrary
655     const int32_t maxMicros =  20000; // arbitrary
656     int32_t prop = property_get_int32(propertyName, defaultMicros);
657     if (prop < minMicros) {
658         ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
659         prop = minMicros;
660     } else if (prop > maxMicros) {
661         ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
662         prop = maxMicros;
663     }
664     return prop;
665 }
666 
AAudioProperty_getInputMMapOffsetMicros()667 int32_t AAudioProperty_getInputMMapOffsetMicros() {
668     return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC);
669 }
670 
AAudioProperty_getOutputMMapOffsetMicros()671 int32_t AAudioProperty_getOutputMMapOffsetMicros() {
672     return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC);
673 }
674 
AAudioProperty_getLogMask()675 int32_t AAudioProperty_getLogMask() {
676     return property_get_int32(AAUDIO_PROP_LOG_MASK, 0);
677 }
678 
AAudio_isFlushAllowed(aaudio_stream_state_t state)679 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
680     aaudio_result_t result = AAUDIO_OK;
681     switch (state) {
682 // Proceed with flushing.
683         case AAUDIO_STREAM_STATE_OPEN:
684         case AAUDIO_STREAM_STATE_PAUSED:
685         case AAUDIO_STREAM_STATE_STOPPED:
686         case AAUDIO_STREAM_STATE_FLUSHED:
687             break;
688 
689 // Transition from one inactive state to another.
690         case AAUDIO_STREAM_STATE_STARTING:
691         case AAUDIO_STREAM_STATE_STARTED:
692         case AAUDIO_STREAM_STATE_STOPPING:
693         case AAUDIO_STREAM_STATE_PAUSING:
694         case AAUDIO_STREAM_STATE_FLUSHING:
695         case AAUDIO_STREAM_STATE_CLOSING:
696         case AAUDIO_STREAM_STATE_CLOSED:
697         case AAUDIO_STREAM_STATE_DISCONNECTED:
698         default:
699             ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
700                   aaudio::AudioGlobal_convertStreamStateToText(state));
701             result =  AAUDIO_ERROR_INVALID_STATE;
702             break;
703     }
704     return result;
705 }
706 
707 namespace {
708 
aidl2legacy_aaudio_policy(AudioMMapPolicy aidl)709 aaudio_policy_t aidl2legacy_aaudio_policy(AudioMMapPolicy aidl) {
710     switch (aidl) {
711         case AudioMMapPolicy::NEVER:
712             return AAUDIO_POLICY_NEVER;
713         case AudioMMapPolicy::AUTO:
714             return AAUDIO_POLICY_AUTO;
715         case AudioMMapPolicy::ALWAYS:
716             return AAUDIO_POLICY_ALWAYS;
717         case AudioMMapPolicy::UNSPECIFIED:
718         default:
719             return AAUDIO_UNSPECIFIED;
720     }
721 }
722 
723 } // namespace
724 
AAudio_getAAudioPolicy(const std::vector<AudioMMapPolicyInfo> & policyInfos,AudioMMapPolicy defaultPolicy)725 aaudio_policy_t AAudio_getAAudioPolicy(const std::vector<AudioMMapPolicyInfo>& policyInfos,
726                                        AudioMMapPolicy defaultPolicy) {
727     AudioMMapPolicy policy = defaultPolicy;
728     for (const auto& policyInfo : policyInfos) {
729         if (policyInfo.mmapPolicy == AudioMMapPolicy::NEVER) {
730             policy = policyInfo.mmapPolicy;
731         } else if (policyInfo.mmapPolicy == AudioMMapPolicy::AUTO ||
732                    policyInfo.mmapPolicy == AudioMMapPolicy::ALWAYS) {
733             return AAUDIO_POLICY_AUTO;
734         }
735     }
736     return aidl2legacy_aaudio_policy(policy);
737 }
738 
AAudioConvert_aaudioToAndroidDeviceType(AAudio_DeviceType device,aaudio_direction_t direction)739 audio_devices_t AAudioConvert_aaudioToAndroidDeviceType(AAudio_DeviceType device,
740                                                         aaudio_direction_t direction) {
741     if (direction == AAUDIO_DIRECTION_INPUT) {
742         switch (device) {
743             case AAUDIO_DEVICE_BUILTIN_MIC:
744                 return AUDIO_DEVICE_IN_BUILTIN_MIC;
745             case AAUDIO_DEVICE_BLUETOOTH_SCO:
746                 return AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
747             case AAUDIO_DEVICE_WIRED_HEADSET:
748                 return AUDIO_DEVICE_IN_WIRED_HEADSET;
749             case AAUDIO_DEVICE_HDMI:
750                 return AUDIO_DEVICE_IN_HDMI;
751             case AAUDIO_DEVICE_TELEPHONY:
752                 return AUDIO_DEVICE_IN_TELEPHONY_RX;
753             case AAUDIO_DEVICE_DOCK:
754                 return AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
755             case AAUDIO_DEVICE_DOCK_ANALOG:
756                 return AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
757             case AAUDIO_DEVICE_USB_ACCESSORY:
758                 return AUDIO_DEVICE_IN_USB_ACCESSORY;
759             case AAUDIO_DEVICE_USB_DEVICE:
760                 return AUDIO_DEVICE_IN_USB_DEVICE;
761             case AAUDIO_DEVICE_USB_HEADSET:
762                 return AUDIO_DEVICE_IN_USB_HEADSET;
763             case AAUDIO_DEVICE_FM_TUNER:
764                 return AUDIO_DEVICE_IN_FM_TUNER;
765             case AAUDIO_DEVICE_TV_TUNER:
766                 return AUDIO_DEVICE_IN_TV_TUNER;
767             case AAUDIO_DEVICE_LINE_ANALOG:
768                 return AUDIO_DEVICE_IN_LINE;
769             case AAUDIO_DEVICE_LINE_DIGITAL:
770                 return AUDIO_DEVICE_IN_SPDIF;
771             case AAUDIO_DEVICE_BLUETOOTH_A2DP:
772                 return AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
773             case AAUDIO_DEVICE_IP:
774                 return AUDIO_DEVICE_IN_IP;
775             case AAUDIO_DEVICE_BUS:
776                 return AUDIO_DEVICE_IN_BUS;
777             case AAUDIO_DEVICE_REMOTE_SUBMIX:
778                 return AUDIO_DEVICE_IN_REMOTE_SUBMIX;
779             case AAUDIO_DEVICE_BLE_HEADSET:
780                 return AUDIO_DEVICE_IN_BLE_HEADSET;
781             case AAUDIO_DEVICE_HDMI_ARC:
782                 return AUDIO_DEVICE_IN_HDMI_ARC;
783             case AAUDIO_DEVICE_HDMI_EARC:
784                 return AUDIO_DEVICE_IN_HDMI_EARC;
785             default:
786                 break;
787         }
788     } else {
789         switch (device) {
790             case AAUDIO_DEVICE_BUILTIN_EARPIECE:
791                 return AUDIO_DEVICE_OUT_EARPIECE;
792             case AAUDIO_DEVICE_BUILTIN_SPEAKER:
793                 return AUDIO_DEVICE_OUT_SPEAKER;
794             case AAUDIO_DEVICE_WIRED_HEADSET:
795                 return AUDIO_DEVICE_OUT_WIRED_HEADSET;
796             case AAUDIO_DEVICE_WIRED_HEADPHONES:
797                 return AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
798             case AAUDIO_DEVICE_LINE_ANALOG:
799                 return AUDIO_DEVICE_OUT_LINE;
800             case AAUDIO_DEVICE_LINE_DIGITAL:
801                 return AUDIO_DEVICE_OUT_SPDIF;
802             case AAUDIO_DEVICE_BLUETOOTH_SCO:
803                 return AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
804             case AAUDIO_DEVICE_BLUETOOTH_A2DP:
805                 return AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
806             case AAUDIO_DEVICE_HDMI:
807                 return AUDIO_DEVICE_OUT_HDMI;
808             case AAUDIO_DEVICE_HDMI_ARC:
809                 return AUDIO_DEVICE_OUT_HDMI_ARC;
810             case AAUDIO_DEVICE_HDMI_EARC:
811                 return AUDIO_DEVICE_OUT_HDMI_EARC;
812             case AAUDIO_DEVICE_USB_DEVICE:
813                 return AUDIO_DEVICE_OUT_USB_DEVICE;
814             case AAUDIO_DEVICE_USB_HEADSET:
815                 return AUDIO_DEVICE_OUT_USB_HEADSET;
816             case AAUDIO_DEVICE_USB_ACCESSORY:
817                 return AUDIO_DEVICE_OUT_USB_ACCESSORY;
818             case AAUDIO_DEVICE_DOCK:
819                 return AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
820             case AAUDIO_DEVICE_DOCK_ANALOG:
821                 return AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
822             case AAUDIO_DEVICE_FM:
823                 return AUDIO_DEVICE_OUT_FM;
824             case AAUDIO_DEVICE_TELEPHONY:
825                 return AUDIO_DEVICE_OUT_TELEPHONY_TX;
826             case AAUDIO_DEVICE_AUX_LINE:
827                 return AUDIO_DEVICE_OUT_AUX_LINE;
828             case AAUDIO_DEVICE_IP:
829                 return AUDIO_DEVICE_OUT_IP;
830             case AAUDIO_DEVICE_BUS:
831                 return AUDIO_DEVICE_OUT_BUS;
832             case AAUDIO_DEVICE_HEARING_AID:
833                 return AUDIO_DEVICE_OUT_HEARING_AID;
834             case AAUDIO_DEVICE_BUILTIN_SPEAKER_SAFE:
835                 return AUDIO_DEVICE_OUT_SPEAKER_SAFE;
836             case AAUDIO_DEVICE_REMOTE_SUBMIX:
837                 return AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
838             case AAUDIO_DEVICE_BLE_HEADSET:
839                 return AUDIO_DEVICE_OUT_BLE_HEADSET;
840             case AAUDIO_DEVICE_BLE_SPEAKER:
841                 return AUDIO_DEVICE_OUT_BLE_SPEAKER;
842             case AAUDIO_DEVICE_BLE_BROADCAST:
843                 return AUDIO_DEVICE_OUT_BLE_BROADCAST;
844             default:
845                 break;
846         }
847     }
848     return AUDIO_DEVICE_NONE;
849 }
850 
AAudioConvert_androidToAAudioMMapPolicy(AudioMMapPolicy policy)851 aaudio_policy_t AAudioConvert_androidToAAudioMMapPolicy(AudioMMapPolicy policy) {
852     switch (policy) {
853         case AudioMMapPolicy::AUTO:
854             return AAUDIO_POLICY_AUTO;
855         case AudioMMapPolicy::ALWAYS:
856             return AAUDIO_POLICY_ALWAYS;
857         case AudioMMapPolicy::NEVER:
858         case AudioMMapPolicy::UNSPECIFIED:
859         default:
860             return AAUDIO_POLICY_NEVER;
861     }
862 }
863