1 /* 2 * Copyright (C) 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 <inttypes.h> 22 #include <mutex> 23 #include <time.h> 24 #include <pthread.h> 25 26 #include <aaudio/AAudio.h> 27 #include <aaudio/AAudioTesting.h> 28 29 #include "AudioClock.h" 30 #include "AudioStreamBuilder.h" 31 #include "AudioStream.h" 32 #include "binding/AAudioCommon.h" 33 #include "client/AudioStreamInternal.h" 34 35 using namespace aaudio; 36 37 // Macros for common code that includes a return. 38 // TODO Consider using do{}while(0) construct. I tried but it hung AndroidStudio 39 #define CONVERT_BUILDER_HANDLE_OR_RETURN() \ 40 convertAAudioBuilderToStreamBuilder(builder); 41 42 #define COMMON_GET_FROM_BUILDER_OR_RETURN(resultPtr) \ 43 CONVERT_BUILDER_HANDLE_OR_RETURN() \ 44 if ((resultPtr) == nullptr) { \ 45 return AAUDIO_ERROR_NULL; \ 46 } 47 48 #define AAUDIO_CASE_ENUM(name) case name: return #name 49 50 AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) { 51 switch (returnCode) { 52 AAUDIO_CASE_ENUM(AAUDIO_OK); 53 AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED); 54 AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT); 55 // reserved 56 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL); 57 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE); 58 // reserved 59 // reserved 60 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE); 61 // reserved 62 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED); 63 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE); 64 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES); 65 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY); 66 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL); 67 AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT); 68 AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK); 69 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT); 70 AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE); 71 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE); 72 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE); 73 } 74 return "Unrecognized AAudio error."; 75 } 76 77 AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) { 78 switch (state) { 79 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED); 80 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN); 81 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN); 82 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING); 83 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED); 84 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING); 85 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED); 86 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING); 87 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED); 88 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING); 89 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED); 90 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED); 91 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING); 92 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED); 93 } 94 return "Unrecognized AAudio state."; 95 } 96 97 #undef AAUDIO_CASE_ENUM 98 99 100 /****************************************** 101 * Static globals. 102 */ 103 static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED; 104 105 static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream) 106 { 107 return (AudioStream*) stream; 108 } 109 110 static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder* builder) 111 { 112 return (AudioStreamBuilder*) builder; 113 } 114 115 AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder) 116 { 117 AudioStreamBuilder *audioStreamBuilder = new(std::nothrow) AudioStreamBuilder(); 118 if (audioStreamBuilder == nullptr) { 119 return AAUDIO_ERROR_NO_MEMORY; 120 } 121 *builder = (AAudioStreamBuilder*) audioStreamBuilder; 122 return AAUDIO_OK; 123 } 124 125 AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder, 126 aaudio_performance_mode_t mode) 127 { 128 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 129 streamBuilder->setPerformanceMode(mode); 130 } 131 132 AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder, 133 int32_t deviceId) 134 { 135 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 136 streamBuilder->setDeviceId(deviceId); 137 } 138 139 AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder, 140 int32_t sampleRate) 141 { 142 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 143 streamBuilder->setSampleRate(sampleRate); 144 } 145 146 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder, 147 int32_t channelCount) 148 { 149 AAudioStreamBuilder_setSamplesPerFrame(builder, channelCount); 150 } 151 152 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder, 153 int32_t samplesPerFrame) 154 { 155 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 156 streamBuilder->setSamplesPerFrame(samplesPerFrame); 157 } 158 159 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder, 160 aaudio_direction_t direction) 161 { 162 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 163 streamBuilder->setDirection(direction); 164 } 165 166 AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder, 167 aaudio_format_t format) 168 { 169 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 170 // Use audio_format_t everywhere internally. 171 const audio_format_t internalFormat = AAudioConvert_aaudioToAndroidDataFormat(format); 172 streamBuilder->setFormat(internalFormat); 173 } 174 175 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder, 176 aaudio_sharing_mode_t sharingMode) 177 { 178 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 179 streamBuilder->setSharingMode(sharingMode); 180 } 181 182 AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder, 183 aaudio_usage_t usage) { 184 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 185 streamBuilder->setUsage(usage); 186 } 187 188 AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder, 189 aaudio_content_type_t contentType) { 190 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 191 streamBuilder->setContentType(contentType); 192 } 193 194 AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder, 195 aaudio_input_preset_t inputPreset) { 196 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 197 streamBuilder->setInputPreset(inputPreset); 198 } 199 200 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder, 201 int32_t frames) 202 { 203 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 204 streamBuilder->setBufferCapacity(frames); 205 } 206 207 AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy( 208 AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t policy) { 209 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 210 streamBuilder->setAllowedCapturePolicy(policy); 211 } 212 213 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder, 214 aaudio_session_id_t sessionId) 215 { 216 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 217 streamBuilder->setSessionId(sessionId); 218 } 219 220 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder, 221 AAudioStream_dataCallback callback, 222 void *userData) 223 { 224 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 225 streamBuilder->setDataCallbackProc(callback); 226 streamBuilder->setDataCallbackUserData(userData); 227 } 228 229 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder, 230 AAudioStream_errorCallback callback, 231 void *userData) 232 { 233 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 234 streamBuilder->setErrorCallbackProc(callback); 235 streamBuilder->setErrorCallbackUserData(userData); 236 } 237 238 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder, 239 int32_t frames) 240 { 241 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 242 streamBuilder->setFramesPerDataCallback(frames); 243 } 244 245 AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder, 246 AAudioStream** streamPtr) 247 { 248 AudioStream *audioStream = nullptr; 249 aaudio_stream_id_t id = 0; 250 // Please leave these logs because they are very helpful when debugging. 251 ALOGI("%s() called ----------------------------------------", __func__); 252 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr); 253 aaudio_result_t result = streamBuilder->build(&audioStream); 254 if (result == AAUDIO_OK) { 255 audioStream->registerPlayerBase(); 256 *streamPtr = (AAudioStream*) audioStream; 257 id = audioStream->getId(); 258 } else { 259 *streamPtr = nullptr; 260 } 261 ALOGI("%s() returns %d = %s for s#%u ----------------", 262 __func__, result, AAudio_convertResultToText(result), id); 263 return result; 264 } 265 266 AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* builder) 267 { 268 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 269 if (streamBuilder != nullptr) { 270 delete streamBuilder; 271 return AAUDIO_OK; 272 } 273 return AAUDIO_ERROR_NULL; 274 } 275 276 AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* stream) 277 { 278 aaudio_result_t result = AAUDIO_ERROR_NULL; 279 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 280 if (audioStream != nullptr) { 281 aaudio_stream_id_t id = audioStream->getId(); 282 ALOGD("%s(s#%u) called ---------------", __func__, id); 283 result = audioStream->safeClose(); 284 // Close will only fail if called illegally, for example, from a callback. 285 // That would result in deleting an active stream, which would cause a crash. 286 if (result == AAUDIO_OK) { 287 audioStream->unregisterPlayerBase(); 288 delete audioStream; 289 } else { 290 ALOGW("%s attempt to close failed. Close it from another thread.", __func__); 291 } 292 ALOGD("%s(s#%u) returned %d ---------", __func__, id, result); 293 } 294 return result; 295 } 296 297 AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* stream) 298 { 299 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 300 aaudio_stream_id_t id = audioStream->getId(); 301 ALOGD("%s(s#%u) called --------------", __func__, id); 302 aaudio_result_t result = audioStream->systemStart(); 303 ALOGD("%s(s#%u) returned %d ---------", __func__, id, result); 304 return result; 305 } 306 307 AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* stream) 308 { 309 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 310 ALOGD("%s(s#%u) called", __func__, audioStream->getId()); 311 return audioStream->systemPause(); 312 } 313 314 AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream) 315 { 316 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 317 ALOGD("%s(s#%u) called", __func__, audioStream->getId()); 318 return audioStream->safeFlush(); 319 } 320 321 AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* stream) 322 { 323 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 324 ALOGD("%s(s#%u) called", __func__, audioStream->getId()); 325 return audioStream->systemStopFromApp(); 326 } 327 328 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream, 329 aaudio_stream_state_t inputState, 330 aaudio_stream_state_t *nextState, 331 int64_t timeoutNanoseconds) 332 { 333 334 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 335 return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); 336 } 337 338 // ============================================================ 339 // Stream - non-blocking I/O 340 // ============================================================ 341 342 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream, 343 void *buffer, 344 int32_t numFrames, 345 int64_t timeoutNanoseconds) 346 { 347 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 348 if (buffer == nullptr) { 349 return AAUDIO_ERROR_NULL; 350 } 351 if (numFrames < 0) { 352 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 353 } else if (numFrames == 0) { 354 return 0; 355 } 356 357 aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds); 358 359 return result; 360 } 361 362 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream, 363 const void *buffer, 364 int32_t numFrames, 365 int64_t timeoutNanoseconds) 366 { 367 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 368 if (buffer == nullptr) { 369 return AAUDIO_ERROR_NULL; 370 } 371 372 // Don't allow writes when playing with a callback. 373 if (audioStream->isDataCallbackActive()) { 374 ALOGD("Cannot write to a callback stream when running."); 375 return AAUDIO_ERROR_INVALID_STATE; 376 } 377 378 if (numFrames < 0) { 379 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 380 } else if (numFrames == 0) { 381 return 0; 382 } 383 384 aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds); 385 386 return result; 387 } 388 389 // ============================================================ 390 // Stream - queries 391 // ============================================================ 392 393 AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) 394 { 395 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 396 return audioStream->getSampleRate(); 397 } 398 399 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) 400 { 401 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 402 return audioStream->getSamplesPerFrame(); 403 } 404 405 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) 406 { 407 return AAudioStream_getChannelCount(stream); 408 } 409 410 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) 411 { 412 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 413 return audioStream->getState(); 414 } 415 416 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) 417 { 418 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 419 // Use audio_format_t internally. 420 audio_format_t internalFormat = audioStream->getFormat(); 421 return AAudioConvert_androidToAAudioDataFormat(internalFormat); 422 } 423 424 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream, 425 int32_t requestedFrames) 426 { 427 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 428 return audioStream->setBufferSize(requestedFrames); 429 } 430 431 AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) 432 { 433 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 434 return audioStream->getBufferSize(); 435 } 436 437 AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) 438 { 439 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 440 return audioStream->getDirection(); 441 } 442 443 AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) 444 { 445 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 446 return audioStream->getFramesPerBurst(); 447 } 448 449 AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) 450 { 451 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 452 return audioStream->getFramesPerDataCallback(); 453 } 454 455 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) 456 { 457 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 458 return audioStream->getBufferCapacity(); 459 } 460 461 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) 462 { 463 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 464 return audioStream->getXRunCount(); 465 } 466 467 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream) 468 { 469 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 470 return audioStream->getPerformanceMode(); 471 } 472 473 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) 474 { 475 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 476 return audioStream->getDeviceId(); 477 } 478 479 AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream) 480 { 481 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 482 return audioStream->getSharingMode(); 483 } 484 485 AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream) 486 { 487 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 488 return audioStream->getUsage(); 489 } 490 491 AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream) 492 { 493 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 494 return audioStream->getContentType(); 495 } 496 497 AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream) 498 { 499 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 500 return audioStream->getInputPreset(); 501 } 502 503 AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy( 504 AAudioStream* stream) 505 { 506 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 507 return audioStream->getAllowedCapturePolicy(); 508 } 509 510 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream) 511 { 512 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 513 return audioStream->getSessionId(); 514 } 515 516 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) 517 { 518 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 519 return audioStream->getFramesWritten(); 520 } 521 522 AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) 523 { 524 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 525 return audioStream->getFramesRead(); 526 } 527 528 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream, 529 clockid_t clockid, 530 int64_t *framePosition, 531 int64_t *timeNanoseconds) 532 { 533 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 534 if (framePosition == nullptr) { 535 return AAUDIO_ERROR_NULL; 536 } else if (timeNanoseconds == nullptr) { 537 return AAUDIO_ERROR_NULL; 538 } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) { 539 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 540 } 541 542 return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds); 543 } 544 545 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() { 546 return s_MMapPolicy; 547 } 548 549 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) { 550 aaudio_result_t result = AAUDIO_OK; 551 switch(policy) { 552 case AAUDIO_UNSPECIFIED: 553 case AAUDIO_POLICY_NEVER: 554 case AAUDIO_POLICY_AUTO: 555 case AAUDIO_POLICY_ALWAYS: 556 s_MMapPolicy = policy; 557 break; 558 default: 559 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 560 break; 561 } 562 return result; 563 } 564 565 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream) 566 { 567 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 568 return audioStream->isMMap(); 569 } 570