• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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