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 // This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data. 37 // It is designed to allow occasional transient peaks. 38 #define MAX_HEADROOM (1.41253754f) 39 #define MIN_HEADROOM (0 - MAX_HEADROOM) 40 41 int32_t AAudioConvert_formatToSizeInBytes(aaudio_format_t format) { 42 int32_t size = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 43 switch (format) { 44 case AAUDIO_FORMAT_PCM_I16: 45 size = sizeof(int16_t); 46 break; 47 case AAUDIO_FORMAT_PCM_FLOAT: 48 size = sizeof(float); 49 break; 50 default: 51 break; 52 } 53 return size; 54 } 55 56 // TODO expose and call clamp16_from_float function in primitives.h 57 static inline int16_t clamp16_from_float(float f) { 58 static const float scale = 1 << 15; 59 return (int16_t) roundf(fmaxf(fminf(f * scale, scale - 1.f), -scale)); 60 } 61 62 // Clip to valid range of a float sample to prevent excessive volume. 63 // By using fmin and fmax we also protect against NaN. 64 static float clipToMinMaxHeadroom(float input) { 65 return fmin(MAX_HEADROOM, fmax(MIN_HEADROOM, input)); 66 } 67 68 static float clipAndClampFloatToPcm16(float sample, float scaler) { 69 // Clip to valid range of a float sample to prevent excessive volume. 70 sample = clipToMinMaxHeadroom(sample); 71 72 // Scale and convert to a short. 73 float fval = sample * scaler; 74 return clamp16_from_float(fval); 75 } 76 77 void AAudioConvert_floatToPcm16(const float *source, 78 int16_t *destination, 79 int32_t numSamples, 80 float amplitude) { 81 const float scaler = amplitude; 82 for (int i = 0; i < numSamples; i++) { 83 float sample = *source++; 84 *destination++ = clipAndClampFloatToPcm16(sample, scaler); 85 } 86 } 87 88 void AAudioConvert_floatToPcm16(const float *source, 89 int16_t *destination, 90 int32_t numFrames, 91 int32_t samplesPerFrame, 92 float amplitude1, 93 float amplitude2) { 94 float scaler = amplitude1; 95 // divide by numFrames so that we almost reach amplitude2 96 float delta = (amplitude2 - amplitude1) / numFrames; 97 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 98 for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) { 99 float sample = *source++; 100 *destination++ = clipAndClampFloatToPcm16(sample, scaler); 101 } 102 scaler += delta; 103 } 104 } 105 106 #define SHORT_SCALE 32768 107 108 void AAudioConvert_pcm16ToFloat(const int16_t *source, 109 float *destination, 110 int32_t numSamples, 111 float amplitude) { 112 const float scaler = amplitude / SHORT_SCALE; 113 for (int i = 0; i < numSamples; i++) { 114 destination[i] = source[i] * scaler; 115 } 116 } 117 118 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 119 void AAudioConvert_pcm16ToFloat(const int16_t *source, 120 float *destination, 121 int32_t numFrames, 122 int32_t samplesPerFrame, 123 float amplitude1, 124 float amplitude2) { 125 float scaler = amplitude1 / SHORT_SCALE; 126 const float delta = (amplitude2 - amplitude1) / (SHORT_SCALE * (float) numFrames); 127 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 128 for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) { 129 *destination++ = *source++ * scaler; 130 } 131 scaler += delta; 132 } 133 } 134 135 136 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 137 void AAudio_linearRamp(const float *source, 138 float *destination, 139 int32_t numFrames, 140 int32_t samplesPerFrame, 141 float amplitude1, 142 float amplitude2) { 143 float scaler = amplitude1; 144 const float delta = (amplitude2 - amplitude1) / numFrames; 145 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 146 for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) { 147 float sample = *source++; 148 // Clip to valid range of a float sample to prevent excessive volume. 149 sample = clipToMinMaxHeadroom(sample); 150 151 *destination++ = sample * scaler; 152 } 153 scaler += delta; 154 } 155 } 156 157 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 158 void AAudio_linearRamp(const int16_t *source, 159 int16_t *destination, 160 int32_t numFrames, 161 int32_t samplesPerFrame, 162 float amplitude1, 163 float amplitude2) { 164 // Because we are converting from int16 to 1nt16, we do not have to scale by 1/32768. 165 float scaler = amplitude1; 166 const float delta = (amplitude2 - amplitude1) / numFrames; 167 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 168 for (int sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) { 169 // No need to clip because int16_t range is inherently limited. 170 float sample = *source++ * scaler; 171 *destination++ = (int16_t) roundf(sample); 172 } 173 scaler += delta; 174 } 175 } 176 177 // ************************************************************************************* 178 // Convert Mono To Stereo at the same time as converting format. 179 void AAudioConvert_formatMonoToStereo(const float *source, 180 int16_t *destination, 181 int32_t numFrames, 182 float amplitude) { 183 const float scaler = amplitude; 184 for (int i = 0; i < numFrames; i++) { 185 float sample = *source++; 186 int16_t sample16 = clipAndClampFloatToPcm16(sample, scaler); 187 *destination++ = sample16; 188 *destination++ = sample16; 189 } 190 } 191 192 void AAudioConvert_formatMonoToStereo(const float *source, 193 int16_t *destination, 194 int32_t numFrames, 195 float amplitude1, 196 float amplitude2) { 197 // divide by numFrames so that we almost reach amplitude2 198 const float delta = (amplitude2 - amplitude1) / numFrames; 199 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 200 const float scaler = amplitude1 + (frameIndex * delta); 201 const float sample = *source++; 202 int16_t sample16 = clipAndClampFloatToPcm16(sample, scaler); 203 *destination++ = sample16; 204 *destination++ = sample16; 205 } 206 } 207 208 void AAudioConvert_formatMonoToStereo(const int16_t *source, 209 float *destination, 210 int32_t numFrames, 211 float amplitude) { 212 const float scaler = amplitude / SHORT_SCALE; 213 for (int i = 0; i < numFrames; i++) { 214 float sample = source[i] * scaler; 215 *destination++ = sample; 216 *destination++ = sample; 217 } 218 } 219 220 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 221 void AAudioConvert_formatMonoToStereo(const int16_t *source, 222 float *destination, 223 int32_t numFrames, 224 float amplitude1, 225 float amplitude2) { 226 const float scaler1 = amplitude1 / SHORT_SCALE; 227 const float delta = (amplitude2 - amplitude1) / (SHORT_SCALE * (float) numFrames); 228 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 229 float scaler = scaler1 + (frameIndex * delta); 230 float sample = source[frameIndex] * scaler; 231 *destination++ = sample; 232 *destination++ = sample; 233 } 234 } 235 236 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 237 void AAudio_linearRampMonoToStereo(const float *source, 238 float *destination, 239 int32_t numFrames, 240 float amplitude1, 241 float amplitude2) { 242 const float delta = (amplitude2 - amplitude1) / numFrames; 243 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 244 float sample = *source++; 245 246 // Clip to valid range of a float sample to prevent excessive volume. 247 sample = clipToMinMaxHeadroom(sample); 248 249 const float scaler = amplitude1 + (frameIndex * delta); 250 float sampleScaled = sample * scaler; 251 *destination++ = sampleScaled; 252 *destination++ = sampleScaled; 253 } 254 } 255 256 // This code assumes amplitude1 and amplitude2 are between 0.0 and 1.0 257 void AAudio_linearRampMonoToStereo(const int16_t *source, 258 int16_t *destination, 259 int32_t numFrames, 260 float amplitude1, 261 float amplitude2) { 262 // Because we are converting from int16 to 1nt16, we do not have to scale by 1/32768. 263 const float delta = (amplitude2 - amplitude1) / numFrames; 264 for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { 265 const float scaler = amplitude1 + (frameIndex * delta); 266 // No need to clip because int16_t range is inherently limited. 267 const float sample = *source++ * scaler; 268 int16_t sample16 = (int16_t) roundf(sample); 269 *destination++ = sample16; 270 *destination++ = sample16; 271 } 272 } 273 274 // ************************************************************************************* 275 void AAudioDataConverter::convert( 276 const FormattedData &source, 277 const FormattedData &destination, 278 int32_t numFrames, 279 float levelFrom, 280 float levelTo) { 281 282 if (source.channelCount == 1 && destination.channelCount == 2) { 283 convertMonoToStereo(source, 284 destination, 285 numFrames, 286 levelFrom, 287 levelTo); 288 } else { 289 // We only support mono to stereo conversion. Otherwise source and destination 290 // must match. 291 assert(source.channelCount == destination.channelCount); 292 convertChannelsMatch(source, 293 destination, 294 numFrames, 295 levelFrom, 296 levelTo); 297 } 298 } 299 300 void AAudioDataConverter::convertMonoToStereo( 301 const FormattedData &source, 302 const FormattedData &destination, 303 int32_t numFrames, 304 float levelFrom, 305 float levelTo) { 306 307 // The formats are validated when the stream is opened so we do not have to 308 // check for illegal combinations here. 309 if (source.format == AAUDIO_FORMAT_PCM_FLOAT) { 310 if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) { 311 AAudio_linearRampMonoToStereo( 312 (const float *) source.data, 313 (float *) destination.data, 314 numFrames, 315 levelFrom, 316 levelTo); 317 } else if (destination.format == AAUDIO_FORMAT_PCM_I16) { 318 if (levelFrom != levelTo) { 319 AAudioConvert_formatMonoToStereo( 320 (const float *) source.data, 321 (int16_t *) destination.data, 322 numFrames, 323 levelFrom, 324 levelTo); 325 } else { 326 AAudioConvert_formatMonoToStereo( 327 (const float *) source.data, 328 (int16_t *) destination.data, 329 numFrames, 330 levelTo); 331 } 332 } 333 } else if (source.format == AAUDIO_FORMAT_PCM_I16) { 334 if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) { 335 if (levelFrom != levelTo) { 336 AAudioConvert_formatMonoToStereo( 337 (const int16_t *) source.data, 338 (float *) destination.data, 339 numFrames, 340 levelFrom, 341 levelTo); 342 } else { 343 AAudioConvert_formatMonoToStereo( 344 (const int16_t *) source.data, 345 (float *) destination.data, 346 numFrames, 347 levelTo); 348 } 349 } else if (destination.format == AAUDIO_FORMAT_PCM_I16) { 350 AAudio_linearRampMonoToStereo( 351 (const int16_t *) source.data, 352 (int16_t *) destination.data, 353 numFrames, 354 levelFrom, 355 levelTo); 356 } 357 } 358 } 359 360 void AAudioDataConverter::convertChannelsMatch( 361 const FormattedData &source, 362 const FormattedData &destination, 363 int32_t numFrames, 364 float levelFrom, 365 float levelTo) { 366 const int32_t numSamples = numFrames * source.channelCount; 367 368 // The formats are validated when the stream is opened so we do not have to 369 // check for illegal combinations here. 370 if (source.format == AAUDIO_FORMAT_PCM_FLOAT) { 371 if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) { 372 AAudio_linearRamp( 373 (const float *) source.data, 374 (float *) destination.data, 375 numFrames, 376 source.channelCount, 377 levelFrom, 378 levelTo); 379 } else if (destination.format == AAUDIO_FORMAT_PCM_I16) { 380 if (levelFrom != levelTo) { 381 AAudioConvert_floatToPcm16( 382 (const float *) source.data, 383 (int16_t *) destination.data, 384 numFrames, 385 source.channelCount, 386 levelFrom, 387 levelTo); 388 } else { 389 AAudioConvert_floatToPcm16( 390 (const float *) source.data, 391 (int16_t *) destination.data, 392 numSamples, 393 levelTo); 394 } 395 } 396 } else if (source.format == AAUDIO_FORMAT_PCM_I16) { 397 if (destination.format == AAUDIO_FORMAT_PCM_FLOAT) { 398 if (levelFrom != levelTo) { 399 AAudioConvert_pcm16ToFloat( 400 (const int16_t *) source.data, 401 (float *) destination.data, 402 numFrames, 403 source.channelCount, 404 levelFrom, 405 levelTo); 406 } else { 407 AAudioConvert_pcm16ToFloat( 408 (const int16_t *) source.data, 409 (float *) destination.data, 410 numSamples, 411 levelTo); 412 } 413 } else if (destination.format == AAUDIO_FORMAT_PCM_I16) { 414 AAudio_linearRamp( 415 (const int16_t *) source.data, 416 (int16_t *) destination.data, 417 numFrames, 418 source.channelCount, 419 levelFrom, 420 levelTo); 421 } 422 } 423 } 424 425 status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) { 426 // This covers the case for AAUDIO_OK and for positive results. 427 if (result >= 0) { 428 return result; 429 } 430 status_t status; 431 switch (result) { 432 case AAUDIO_ERROR_DISCONNECTED: 433 case AAUDIO_ERROR_NO_SERVICE: 434 status = DEAD_OBJECT; 435 break; 436 case AAUDIO_ERROR_INVALID_HANDLE: 437 status = BAD_TYPE; 438 break; 439 case AAUDIO_ERROR_INVALID_STATE: 440 status = INVALID_OPERATION; 441 break; 442 case AAUDIO_ERROR_INVALID_RATE: 443 case AAUDIO_ERROR_INVALID_FORMAT: 444 case AAUDIO_ERROR_ILLEGAL_ARGUMENT: 445 case AAUDIO_ERROR_OUT_OF_RANGE: 446 status = BAD_VALUE; 447 break; 448 case AAUDIO_ERROR_WOULD_BLOCK: 449 status = WOULD_BLOCK; 450 break; 451 case AAUDIO_ERROR_NULL: 452 status = UNEXPECTED_NULL; 453 break; 454 case AAUDIO_ERROR_UNAVAILABLE: 455 status = NOT_ENOUGH_DATA; 456 break; 457 458 // TODO translate these result codes 459 case AAUDIO_ERROR_INTERNAL: 460 case AAUDIO_ERROR_UNIMPLEMENTED: 461 case AAUDIO_ERROR_NO_FREE_HANDLES: 462 case AAUDIO_ERROR_NO_MEMORY: 463 case AAUDIO_ERROR_TIMEOUT: 464 default: 465 status = UNKNOWN_ERROR; 466 break; 467 } 468 return status; 469 } 470 471 aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) { 472 // This covers the case for OK and for positive result. 473 if (status >= 0) { 474 return status; 475 } 476 aaudio_result_t result; 477 switch (status) { 478 case BAD_TYPE: 479 result = AAUDIO_ERROR_INVALID_HANDLE; 480 break; 481 case DEAD_OBJECT: 482 result = AAUDIO_ERROR_NO_SERVICE; 483 break; 484 case INVALID_OPERATION: 485 result = AAUDIO_ERROR_INVALID_STATE; 486 break; 487 case UNEXPECTED_NULL: 488 result = AAUDIO_ERROR_NULL; 489 break; 490 case BAD_VALUE: 491 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 492 break; 493 case WOULD_BLOCK: 494 result = AAUDIO_ERROR_WOULD_BLOCK; 495 break; 496 case NOT_ENOUGH_DATA: 497 result = AAUDIO_ERROR_UNAVAILABLE; 498 break; 499 default: 500 result = AAUDIO_ERROR_INTERNAL; 501 break; 502 } 503 return result; 504 } 505 506 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) { 507 // If not a regular sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE. 508 return (sessionId == AAUDIO_SESSION_ID_ALLOCATE || sessionId == AAUDIO_SESSION_ID_NONE) 509 ? AUDIO_SESSION_ALLOCATE 510 : (audio_session_t) sessionId; 511 } 512 513 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) { 514 audio_format_t androidFormat; 515 switch (aaudioFormat) { 516 case AAUDIO_FORMAT_PCM_I16: 517 androidFormat = AUDIO_FORMAT_PCM_16_BIT; 518 break; 519 case AAUDIO_FORMAT_PCM_FLOAT: 520 androidFormat = AUDIO_FORMAT_PCM_FLOAT; 521 break; 522 default: 523 androidFormat = AUDIO_FORMAT_DEFAULT; 524 ALOGE("AAudioConvert_aaudioToAndroidDataFormat 0x%08X unrecognized", aaudioFormat); 525 break; 526 } 527 return androidFormat; 528 } 529 530 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) { 531 aaudio_format_t aaudioFormat = AAUDIO_FORMAT_INVALID; 532 switch (androidFormat) { 533 case AUDIO_FORMAT_PCM_16_BIT: 534 aaudioFormat = AAUDIO_FORMAT_PCM_I16; 535 break; 536 case AUDIO_FORMAT_PCM_FLOAT: 537 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT; 538 break; 539 default: 540 aaudioFormat = AAUDIO_FORMAT_INVALID; 541 ALOGE("AAudioConvert_androidToAAudioDataFormat 0x%08X unrecognized", androidFormat); 542 break; 543 } 544 return aaudioFormat; 545 } 546 547 // Make a message string from the condition. 548 #define STATIC_ASSERT(condition) static_assert(condition, #condition) 549 550 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) { 551 // The public aaudio_content_type_t constants are supposed to have the same 552 // values as the internal audio_content_type_t values. 553 STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA); 554 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION); 555 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING 556 == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING); 557 STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM); 558 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION); 559 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE 560 == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE); 561 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT); 562 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY); 563 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE 564 == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE); 565 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION); 566 STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME); 567 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT); 568 if (usage == AAUDIO_UNSPECIFIED) { 569 usage = AAUDIO_USAGE_MEDIA; 570 } 571 return (audio_usage_t) usage; // same value 572 } 573 574 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) { 575 // The public aaudio_content_type_t constants are supposed to have the same 576 // values as the internal audio_content_type_t values. 577 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC); 578 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH); 579 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION); 580 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE); 581 if (contentType == AAUDIO_UNSPECIFIED) { 582 contentType = AAUDIO_CONTENT_TYPE_MUSIC; 583 } 584 return (audio_content_type_t) contentType; // same value 585 } 586 587 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) { 588 // The public aaudio_input_preset_t constants are supposed to have the same 589 // values as the internal audio_source_t values. 590 STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT); 591 STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC); 592 STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER); 593 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION); 594 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION); 595 STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED); 596 if (preset == AAUDIO_UNSPECIFIED) { 597 preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION; 598 } 599 return (audio_source_t) preset; // same value 600 } 601 602 int32_t AAudioConvert_framesToBytes(int32_t numFrames, 603 int32_t bytesPerFrame, 604 int32_t *sizeInBytes) { 605 *sizeInBytes = 0; 606 607 if (numFrames < 0 || bytesPerFrame < 0) { 608 ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame); 609 return AAUDIO_ERROR_OUT_OF_RANGE; 610 } 611 612 // Prevent numeric overflow. 613 if (numFrames > (INT32_MAX / bytesPerFrame)) { 614 ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame); 615 return AAUDIO_ERROR_OUT_OF_RANGE; 616 } 617 618 *sizeInBytes = numFrames * bytesPerFrame; 619 return AAUDIO_OK; 620 } 621 622 static int32_t AAudioProperty_getMMapProperty(const char *propName, 623 int32_t defaultValue, 624 const char * caller) { 625 int32_t prop = property_get_int32(propName, defaultValue); 626 switch (prop) { 627 case AAUDIO_UNSPECIFIED: 628 case AAUDIO_POLICY_NEVER: 629 case AAUDIO_POLICY_ALWAYS: 630 case AAUDIO_POLICY_AUTO: 631 break; 632 default: 633 ALOGE("%s: invalid = %d", caller, prop); 634 prop = defaultValue; 635 break; 636 } 637 return prop; 638 } 639 640 int32_t AAudioProperty_getMMapPolicy() { 641 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY, 642 AAUDIO_UNSPECIFIED, __func__); 643 } 644 645 int32_t AAudioProperty_getMMapExclusivePolicy() { 646 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY, 647 AAUDIO_UNSPECIFIED, __func__); 648 } 649 650 int32_t AAudioProperty_getMixerBursts() { 651 const int32_t defaultBursts = 2; // arbitrary, use 2 for double buffered 652 const int32_t maxBursts = 1024; // arbitrary 653 int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts); 654 if (prop < 1 || prop > maxBursts) { 655 ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop); 656 prop = defaultBursts; 657 } 658 return prop; 659 } 660 661 int32_t AAudioProperty_getWakeupDelayMicros() { 662 const int32_t minMicros = 0; // arbitrary 663 const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter 664 const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500 665 int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros); 666 if (prop < minMicros) { 667 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros); 668 prop = minMicros; 669 } else if (prop > maxMicros) { 670 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros); 671 prop = maxMicros; 672 } 673 return prop; 674 } 675 676 int32_t AAudioProperty_getMinimumSleepMicros() { 677 const int32_t minMicros = 20; // arbitrary 678 const int32_t defaultMicros = 200; // arbitrary 679 const int32_t maxMicros = 2000; // arbitrary 680 int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros); 681 if (prop < minMicros) { 682 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros); 683 prop = minMicros; 684 } else if (prop > maxMicros) { 685 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros); 686 prop = maxMicros; 687 } 688 return prop; 689 } 690 691 int32_t AAudioProperty_getHardwareBurstMinMicros() { 692 const int32_t defaultMicros = 1000; // arbitrary 693 const int32_t maxMicros = 1000 * 1000; // arbitrary 694 int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros); 695 if (prop < 1 || prop > maxMicros) { 696 ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d, use %d", 697 prop, defaultMicros); 698 prop = defaultMicros; 699 } 700 return prop; 701 } 702 703 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) { 704 aaudio_result_t result = AAUDIO_OK; 705 switch (state) { 706 // Proceed with flushing. 707 case AAUDIO_STREAM_STATE_OPEN: 708 case AAUDIO_STREAM_STATE_PAUSED: 709 case AAUDIO_STREAM_STATE_STOPPED: 710 case AAUDIO_STREAM_STATE_FLUSHED: 711 break; 712 713 // Transition from one inactive state to another. 714 case AAUDIO_STREAM_STATE_STARTING: 715 case AAUDIO_STREAM_STATE_STARTED: 716 case AAUDIO_STREAM_STATE_STOPPING: 717 case AAUDIO_STREAM_STATE_PAUSING: 718 case AAUDIO_STREAM_STATE_FLUSHING: 719 case AAUDIO_STREAM_STATE_CLOSING: 720 case AAUDIO_STREAM_STATE_CLOSED: 721 case AAUDIO_STREAM_STATE_DISCONNECTED: 722 default: 723 ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s", 724 AAudio_convertStreamStateToText(state)); 725 result = AAUDIO_ERROR_INVALID_STATE; 726 break; 727 } 728 return result; 729 } 730