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-base.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 default:
138 androidFormat = AUDIO_FORMAT_INVALID;
139 ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
140 break;
141 }
142 return androidFormat;
143 }
144
AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat)145 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
146 aaudio_format_t aaudioFormat;
147 switch (androidFormat) {
148 case AUDIO_FORMAT_DEFAULT:
149 aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
150 break;
151 case AUDIO_FORMAT_PCM_16_BIT:
152 aaudioFormat = AAUDIO_FORMAT_PCM_I16;
153 break;
154 case AUDIO_FORMAT_PCM_FLOAT:
155 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
156 break;
157 default:
158 aaudioFormat = AAUDIO_FORMAT_INVALID;
159 ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
160 break;
161 }
162 return aaudioFormat;
163 }
164
165 // Make a message string from the condition.
166 #define STATIC_ASSERT(condition) static_assert(condition, #condition)
167
AAudioConvert_usageToInternal(aaudio_usage_t usage)168 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
169 // The public aaudio_content_type_t constants are supposed to have the same
170 // values as the internal audio_content_type_t values.
171 STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
172 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
173 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
174 == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
175 STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
176 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
177 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
178 == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
179 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
180 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
181 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
182 == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
183 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
184 STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
185 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
186 if (usage == AAUDIO_UNSPECIFIED) {
187 usage = AAUDIO_USAGE_MEDIA;
188 }
189 return (audio_usage_t) usage; // same value
190 }
191
AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType)192 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
193 // The public aaudio_content_type_t constants are supposed to have the same
194 // values as the internal audio_content_type_t values.
195 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
196 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
197 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
198 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
199 if (contentType == AAUDIO_UNSPECIFIED) {
200 contentType = AAUDIO_CONTENT_TYPE_MUSIC;
201 }
202 return (audio_content_type_t) contentType; // same value
203 }
204
AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset)205 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
206 // The public aaudio_input_preset_t constants are supposed to have the same
207 // values as the internal audio_source_t values.
208 STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
209 STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
210 STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
211 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
212 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
213 STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
214 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
215 if (preset == AAUDIO_UNSPECIFIED) {
216 preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
217 }
218 return (audio_source_t) preset; // same value
219 }
220
AAudioConvert_allowCapturePolicyToAudioFlagsMask(aaudio_allowed_capture_policy_t policy)221 audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
222 aaudio_allowed_capture_policy_t policy) {
223 switch (policy) {
224 case AAUDIO_UNSPECIFIED:
225 case AAUDIO_ALLOW_CAPTURE_BY_ALL:
226 return AUDIO_FLAG_NONE;
227 case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
228 return AUDIO_FLAG_NO_MEDIA_PROJECTION;
229 case AAUDIO_ALLOW_CAPTURE_BY_NONE:
230 return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE;
231 default:
232 ALOGE("%s() 0x%08X unrecognized", __func__, policy);
233 return AUDIO_FLAG_NONE; //
234 }
235 }
236
AAudioConvert_framesToBytes(int32_t numFrames,int32_t bytesPerFrame,int32_t * sizeInBytes)237 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
238 int32_t bytesPerFrame,
239 int32_t *sizeInBytes) {
240 *sizeInBytes = 0;
241
242 if (numFrames < 0 || bytesPerFrame < 0) {
243 ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
244 return AAUDIO_ERROR_OUT_OF_RANGE;
245 }
246
247 // Prevent numeric overflow.
248 if (numFrames > (INT32_MAX / bytesPerFrame)) {
249 ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
250 return AAUDIO_ERROR_OUT_OF_RANGE;
251 }
252
253 *sizeInBytes = numFrames * bytesPerFrame;
254 return AAUDIO_OK;
255 }
256
AAudioProperty_getMMapProperty(const char * propName,int32_t defaultValue,const char * caller)257 static int32_t AAudioProperty_getMMapProperty(const char *propName,
258 int32_t defaultValue,
259 const char * caller) {
260 int32_t prop = property_get_int32(propName, defaultValue);
261 switch (prop) {
262 case AAUDIO_UNSPECIFIED:
263 case AAUDIO_POLICY_NEVER:
264 case AAUDIO_POLICY_ALWAYS:
265 case AAUDIO_POLICY_AUTO:
266 break;
267 default:
268 ALOGE("%s: invalid = %d", caller, prop);
269 prop = defaultValue;
270 break;
271 }
272 return prop;
273 }
274
AAudioProperty_getMMapPolicy()275 int32_t AAudioProperty_getMMapPolicy() {
276 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY,
277 AAUDIO_UNSPECIFIED, __func__);
278 }
279
AAudioProperty_getMMapExclusivePolicy()280 int32_t AAudioProperty_getMMapExclusivePolicy() {
281 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY,
282 AAUDIO_UNSPECIFIED, __func__);
283 }
284
AAudioProperty_getMixerBursts()285 int32_t AAudioProperty_getMixerBursts() {
286 const int32_t defaultBursts = 2; // arbitrary, use 2 for double buffered
287 const int32_t maxBursts = 1024; // arbitrary
288 int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts);
289 if (prop < 1 || prop > maxBursts) {
290 ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop);
291 prop = defaultBursts;
292 }
293 return prop;
294 }
295
AAudioProperty_getWakeupDelayMicros()296 int32_t AAudioProperty_getWakeupDelayMicros() {
297 const int32_t minMicros = 0; // arbitrary
298 const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter
299 const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500
300 int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros);
301 if (prop < minMicros) {
302 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros);
303 prop = minMicros;
304 } else if (prop > maxMicros) {
305 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros);
306 prop = maxMicros;
307 }
308 return prop;
309 }
310
AAudioProperty_getMinimumSleepMicros()311 int32_t AAudioProperty_getMinimumSleepMicros() {
312 const int32_t minMicros = 20; // arbitrary
313 const int32_t defaultMicros = 200; // arbitrary
314 const int32_t maxMicros = 2000; // arbitrary
315 int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
316 if (prop < minMicros) {
317 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros);
318 prop = minMicros;
319 } else if (prop > maxMicros) {
320 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros);
321 prop = maxMicros;
322 }
323 return prop;
324 }
325
AAudioProperty_getHardwareBurstMinMicros()326 int32_t AAudioProperty_getHardwareBurstMinMicros() {
327 const int32_t defaultMicros = 1000; // arbitrary
328 const int32_t maxMicros = 1000 * 1000; // arbitrary
329 int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros);
330 if (prop < 1 || prop > maxMicros) {
331 ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d, use %d",
332 prop, defaultMicros);
333 prop = defaultMicros;
334 }
335 return prop;
336 }
337
AAudio_isFlushAllowed(aaudio_stream_state_t state)338 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
339 aaudio_result_t result = AAUDIO_OK;
340 switch (state) {
341 // Proceed with flushing.
342 case AAUDIO_STREAM_STATE_OPEN:
343 case AAUDIO_STREAM_STATE_PAUSED:
344 case AAUDIO_STREAM_STATE_STOPPED:
345 case AAUDIO_STREAM_STATE_FLUSHED:
346 break;
347
348 // Transition from one inactive state to another.
349 case AAUDIO_STREAM_STATE_STARTING:
350 case AAUDIO_STREAM_STATE_STARTED:
351 case AAUDIO_STREAM_STATE_STOPPING:
352 case AAUDIO_STREAM_STATE_PAUSING:
353 case AAUDIO_STREAM_STATE_FLUSHING:
354 case AAUDIO_STREAM_STATE_CLOSING:
355 case AAUDIO_STREAM_STATE_CLOSED:
356 case AAUDIO_STREAM_STATE_DISCONNECTED:
357 default:
358 ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
359 aaudio::AudioGlobal_convertStreamStateToText(state));
360 result = AAUDIO_ERROR_INVALID_STATE;
361 break;
362 }
363 return result;
364 }
365