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 <aaudio/AAudioTesting.h> 28 #include <math.h> 29 #include <system/audio-base.h> 30 #include <assert.h> 31 32 #include "utility/AAudioUtilities.h" 33 34 using namespace android; 35 36 status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) { 37 // This covers the case for AAUDIO_OK and for positive results. 38 if (result >= 0) { 39 return result; 40 } 41 status_t status; 42 switch (result) { 43 case AAUDIO_ERROR_DISCONNECTED: 44 case AAUDIO_ERROR_NO_SERVICE: 45 status = DEAD_OBJECT; 46 break; 47 case AAUDIO_ERROR_INVALID_HANDLE: 48 status = BAD_TYPE; 49 break; 50 case AAUDIO_ERROR_INVALID_STATE: 51 status = INVALID_OPERATION; 52 break; 53 case AAUDIO_ERROR_INVALID_RATE: 54 case AAUDIO_ERROR_INVALID_FORMAT: 55 case AAUDIO_ERROR_ILLEGAL_ARGUMENT: 56 case AAUDIO_ERROR_OUT_OF_RANGE: 57 status = BAD_VALUE; 58 break; 59 case AAUDIO_ERROR_WOULD_BLOCK: 60 status = WOULD_BLOCK; 61 break; 62 case AAUDIO_ERROR_NULL: 63 status = UNEXPECTED_NULL; 64 break; 65 case AAUDIO_ERROR_UNAVAILABLE: 66 status = NOT_ENOUGH_DATA; 67 break; 68 69 // TODO translate these result codes 70 case AAUDIO_ERROR_INTERNAL: 71 case AAUDIO_ERROR_UNIMPLEMENTED: 72 case AAUDIO_ERROR_NO_FREE_HANDLES: 73 case AAUDIO_ERROR_NO_MEMORY: 74 case AAUDIO_ERROR_TIMEOUT: 75 default: 76 status = UNKNOWN_ERROR; 77 break; 78 } 79 return status; 80 } 81 82 aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) { 83 // This covers the case for OK and for positive result. 84 if (status >= 0) { 85 return status; 86 } 87 aaudio_result_t result; 88 switch (status) { 89 case BAD_TYPE: 90 result = AAUDIO_ERROR_INVALID_HANDLE; 91 break; 92 case DEAD_OBJECT: 93 result = AAUDIO_ERROR_NO_SERVICE; 94 break; 95 case INVALID_OPERATION: 96 result = AAUDIO_ERROR_INVALID_STATE; 97 break; 98 case UNEXPECTED_NULL: 99 result = AAUDIO_ERROR_NULL; 100 break; 101 case BAD_VALUE: 102 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 103 break; 104 case WOULD_BLOCK: 105 result = AAUDIO_ERROR_WOULD_BLOCK; 106 break; 107 case NOT_ENOUGH_DATA: 108 result = AAUDIO_ERROR_UNAVAILABLE; 109 break; 110 default: 111 result = AAUDIO_ERROR_INTERNAL; 112 break; 113 } 114 return result; 115 } 116 117 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) { 118 // If not a regular sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE. 119 return (sessionId == AAUDIO_SESSION_ID_ALLOCATE || sessionId == AAUDIO_SESSION_ID_NONE) 120 ? AUDIO_SESSION_ALLOCATE 121 : (audio_session_t) sessionId; 122 } 123 124 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) { 125 audio_format_t androidFormat; 126 switch (aaudioFormat) { 127 case AAUDIO_FORMAT_UNSPECIFIED: 128 androidFormat = AUDIO_FORMAT_DEFAULT; 129 break; 130 case AAUDIO_FORMAT_PCM_I16: 131 androidFormat = AUDIO_FORMAT_PCM_16_BIT; 132 break; 133 case AAUDIO_FORMAT_PCM_FLOAT: 134 androidFormat = AUDIO_FORMAT_PCM_FLOAT; 135 break; 136 default: 137 androidFormat = AUDIO_FORMAT_INVALID; 138 ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat); 139 break; 140 } 141 return androidFormat; 142 } 143 144 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) { 145 aaudio_format_t aaudioFormat; 146 switch (androidFormat) { 147 case AUDIO_FORMAT_DEFAULT: 148 aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED; 149 break; 150 case AUDIO_FORMAT_PCM_16_BIT: 151 aaudioFormat = AAUDIO_FORMAT_PCM_I16; 152 break; 153 case AUDIO_FORMAT_PCM_FLOAT: 154 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT; 155 break; 156 default: 157 aaudioFormat = AAUDIO_FORMAT_INVALID; 158 ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat); 159 break; 160 } 161 return aaudioFormat; 162 } 163 164 // Make a message string from the condition. 165 #define STATIC_ASSERT(condition) static_assert(condition, #condition) 166 167 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) { 168 // The public aaudio_content_type_t constants are supposed to have the same 169 // values as the internal audio_content_type_t values. 170 STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA); 171 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION); 172 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING 173 == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING); 174 STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM); 175 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION); 176 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE 177 == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE); 178 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT); 179 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY); 180 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE 181 == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE); 182 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION); 183 STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME); 184 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT); 185 if (usage == AAUDIO_UNSPECIFIED) { 186 usage = AAUDIO_USAGE_MEDIA; 187 } 188 return (audio_usage_t) usage; // same value 189 } 190 191 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) { 192 // The public aaudio_content_type_t constants are supposed to have the same 193 // values as the internal audio_content_type_t values. 194 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC); 195 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH); 196 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION); 197 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE); 198 if (contentType == AAUDIO_UNSPECIFIED) { 199 contentType = AAUDIO_CONTENT_TYPE_MUSIC; 200 } 201 return (audio_content_type_t) contentType; // same value 202 } 203 204 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) { 205 // The public aaudio_input_preset_t constants are supposed to have the same 206 // values as the internal audio_source_t values. 207 STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT); 208 STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC); 209 STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER); 210 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION); 211 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION); 212 STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED); 213 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE); 214 if (preset == AAUDIO_UNSPECIFIED) { 215 preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION; 216 } 217 return (audio_source_t) preset; // same value 218 } 219 220 audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask( 221 aaudio_allowed_capture_policy_t policy) { 222 switch (policy) { 223 case AAUDIO_UNSPECIFIED: 224 case AAUDIO_ALLOW_CAPTURE_BY_ALL: 225 return AUDIO_FLAG_NONE; 226 case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM: 227 return AUDIO_FLAG_NO_MEDIA_PROJECTION; 228 case AAUDIO_ALLOW_CAPTURE_BY_NONE: 229 return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE; 230 default: 231 ALOGE("%s() 0x%08X unrecognized", __func__, policy); 232 return AUDIO_FLAG_NONE; // 233 } 234 } 235 236 int32_t AAudioConvert_framesToBytes(int32_t numFrames, 237 int32_t bytesPerFrame, 238 int32_t *sizeInBytes) { 239 *sizeInBytes = 0; 240 241 if (numFrames < 0 || bytesPerFrame < 0) { 242 ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame); 243 return AAUDIO_ERROR_OUT_OF_RANGE; 244 } 245 246 // Prevent numeric overflow. 247 if (numFrames > (INT32_MAX / bytesPerFrame)) { 248 ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame); 249 return AAUDIO_ERROR_OUT_OF_RANGE; 250 } 251 252 *sizeInBytes = numFrames * bytesPerFrame; 253 return AAUDIO_OK; 254 } 255 256 static int32_t AAudioProperty_getMMapProperty(const char *propName, 257 int32_t defaultValue, 258 const char * caller) { 259 int32_t prop = property_get_int32(propName, defaultValue); 260 switch (prop) { 261 case AAUDIO_UNSPECIFIED: 262 case AAUDIO_POLICY_NEVER: 263 case AAUDIO_POLICY_ALWAYS: 264 case AAUDIO_POLICY_AUTO: 265 break; 266 default: 267 ALOGE("%s: invalid = %d", caller, prop); 268 prop = defaultValue; 269 break; 270 } 271 return prop; 272 } 273 274 int32_t AAudioProperty_getMMapPolicy() { 275 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY, 276 AAUDIO_UNSPECIFIED, __func__); 277 } 278 279 int32_t AAudioProperty_getMMapExclusivePolicy() { 280 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY, 281 AAUDIO_UNSPECIFIED, __func__); 282 } 283 284 int32_t AAudioProperty_getMixerBursts() { 285 const int32_t defaultBursts = 2; // arbitrary, use 2 for double buffered 286 const int32_t maxBursts = 1024; // arbitrary 287 int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts); 288 if (prop < 1 || prop > maxBursts) { 289 ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop); 290 prop = defaultBursts; 291 } 292 return prop; 293 } 294 295 int32_t AAudioProperty_getWakeupDelayMicros() { 296 const int32_t minMicros = 0; // arbitrary 297 const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter 298 const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500 299 int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros); 300 if (prop < minMicros) { 301 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros); 302 prop = minMicros; 303 } else if (prop > maxMicros) { 304 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros); 305 prop = maxMicros; 306 } 307 return prop; 308 } 309 310 int32_t AAudioProperty_getMinimumSleepMicros() { 311 const int32_t minMicros = 20; // arbitrary 312 const int32_t defaultMicros = 200; // arbitrary 313 const int32_t maxMicros = 2000; // arbitrary 314 int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros); 315 if (prop < minMicros) { 316 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros); 317 prop = minMicros; 318 } else if (prop > maxMicros) { 319 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros); 320 prop = maxMicros; 321 } 322 return prop; 323 } 324 325 int32_t AAudioProperty_getHardwareBurstMinMicros() { 326 const int32_t defaultMicros = 1000; // arbitrary 327 const int32_t maxMicros = 1000 * 1000; // arbitrary 328 int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros); 329 if (prop < 1 || prop > maxMicros) { 330 ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d, use %d", 331 prop, defaultMicros); 332 prop = defaultMicros; 333 } 334 return prop; 335 } 336 337 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) { 338 aaudio_result_t result = AAUDIO_OK; 339 switch (state) { 340 // Proceed with flushing. 341 case AAUDIO_STREAM_STATE_OPEN: 342 case AAUDIO_STREAM_STATE_PAUSED: 343 case AAUDIO_STREAM_STATE_STOPPED: 344 case AAUDIO_STREAM_STATE_FLUSHED: 345 break; 346 347 // Transition from one inactive state to another. 348 case AAUDIO_STREAM_STATE_STARTING: 349 case AAUDIO_STREAM_STATE_STARTED: 350 case AAUDIO_STREAM_STATE_STOPPING: 351 case AAUDIO_STREAM_STATE_PAUSING: 352 case AAUDIO_STREAM_STATE_FLUSHING: 353 case AAUDIO_STREAM_STATE_CLOSING: 354 case AAUDIO_STREAM_STATE_CLOSED: 355 case AAUDIO_STREAM_STATE_DISCONNECTED: 356 default: 357 ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s", 358 AAudio_convertStreamStateToText(state)); 359 result = AAUDIO_ERROR_INVALID_STATE; 360 break; 361 } 362 return result; 363 } 364