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