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 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 150 streamBuilder->setSamplesPerFrame(channelCount); 151 } 152 153 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder, 154 int32_t channelCount) 155 { 156 AAudioStreamBuilder_setChannelCount(builder, channelCount); 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 streamBuilder->setFormat(format); 171 } 172 173 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder, 174 aaudio_sharing_mode_t sharingMode) 175 { 176 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 177 streamBuilder->setSharingMode(sharingMode); 178 } 179 180 AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder, 181 aaudio_usage_t usage) { 182 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 183 streamBuilder->setUsage(usage); 184 } 185 186 AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder, 187 aaudio_content_type_t contentType) { 188 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 189 streamBuilder->setContentType(contentType); 190 } 191 192 AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder, 193 aaudio_input_preset_t inputPreset) { 194 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 195 streamBuilder->setInputPreset(inputPreset); 196 } 197 198 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder, 199 int32_t frames) 200 { 201 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 202 streamBuilder->setBufferCapacity(frames); 203 } 204 205 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder, 206 aaudio_session_id_t sessionId) 207 { 208 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 209 streamBuilder->setSessionId(sessionId); 210 } 211 212 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder, 213 AAudioStream_dataCallback callback, 214 void *userData) 215 { 216 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 217 streamBuilder->setDataCallbackProc(callback); 218 streamBuilder->setDataCallbackUserData(userData); 219 } 220 221 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder, 222 AAudioStream_errorCallback callback, 223 void *userData) 224 { 225 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 226 streamBuilder->setErrorCallbackProc(callback); 227 streamBuilder->setErrorCallbackUserData(userData); 228 } 229 230 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder, 231 int32_t frames) 232 { 233 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 234 streamBuilder->setFramesPerDataCallback(frames); 235 } 236 237 AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder, 238 AAudioStream** streamPtr) 239 { 240 AudioStream *audioStream = nullptr; 241 // Please leave these logs because they are very helpful when debugging. 242 ALOGD("AAudioStreamBuilder_openStream() called ----------------------------------------"); 243 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr); 244 aaudio_result_t result = streamBuilder->build(&audioStream); 245 ALOGD("AAudioStreamBuilder_openStream() returns %d = %s for (%p) ----------------", 246 result, AAudio_convertResultToText(result), audioStream); 247 if (result == AAUDIO_OK) { 248 audioStream->registerPlayerBase(); 249 *streamPtr = (AAudioStream*) audioStream; 250 } else { 251 *streamPtr = nullptr; 252 } 253 return result; 254 } 255 256 AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* builder) 257 { 258 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 259 if (streamBuilder != nullptr) { 260 delete streamBuilder; 261 return AAUDIO_OK; 262 } 263 return AAUDIO_ERROR_NULL; 264 } 265 266 AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* stream) 267 { 268 aaudio_result_t result = AAUDIO_ERROR_NULL; 269 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 270 ALOGD("AAudioStream_close(%p) called ---------------", stream); 271 if (audioStream != nullptr) { 272 result = audioStream->safeClose(); 273 // Close will only fail if called illegally, for example, from a callback. 274 // That would result in deleting an active stream, which would cause a crash. 275 if (result == AAUDIO_OK) { 276 audioStream->unregisterPlayerBase(); 277 delete audioStream; 278 } else { 279 ALOGW("%s attempt to close failed. Close it from another thread.", __func__); 280 } 281 } 282 // We're potentially freeing `stream` above, so its use here makes some 283 // static analysis tools unhappy. Casting to uintptr_t helps assure 284 // said tools that we're not doing anything bad here. 285 ALOGD("AAudioStream_close(%#" PRIxPTR ") returned %d ---------", 286 reinterpret_cast<uintptr_t>(stream), result); 287 return result; 288 } 289 290 AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* stream) 291 { 292 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 293 ALOGD("AAudioStream_requestStart(%p) called --------------", stream); 294 aaudio_result_t result = audioStream->systemStart(); 295 ALOGD("AAudioStream_requestStart(%p) returned %d ---------", stream, result); 296 return result; 297 } 298 299 AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* stream) 300 { 301 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 302 ALOGD("AAudioStream_requestPause(%p)", stream); 303 return audioStream->systemPause(); 304 } 305 306 AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream) 307 { 308 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 309 ALOGD("AAudioStream_requestFlush(%p)", stream); 310 return audioStream->safeFlush(); 311 } 312 313 AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* stream) 314 { 315 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 316 ALOGD("AAudioStream_requestStop(%p)", stream); 317 return audioStream->systemStop(); 318 } 319 320 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream, 321 aaudio_stream_state_t inputState, 322 aaudio_stream_state_t *nextState, 323 int64_t timeoutNanoseconds) 324 { 325 326 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 327 return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); 328 } 329 330 // ============================================================ 331 // Stream - non-blocking I/O 332 // ============================================================ 333 334 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream, 335 void *buffer, 336 int32_t numFrames, 337 int64_t timeoutNanoseconds) 338 { 339 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 340 if (buffer == nullptr) { 341 return AAUDIO_ERROR_NULL; 342 } 343 if (numFrames < 0) { 344 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 345 } else if (numFrames == 0) { 346 return 0; 347 } 348 349 aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds); 350 351 return result; 352 } 353 354 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream, 355 const void *buffer, 356 int32_t numFrames, 357 int64_t timeoutNanoseconds) 358 { 359 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 360 if (buffer == nullptr) { 361 return AAUDIO_ERROR_NULL; 362 } 363 364 // Don't allow writes when playing with a callback. 365 if (audioStream->isDataCallbackActive()) { 366 ALOGE("Cannot write to a callback stream when running."); 367 return AAUDIO_ERROR_INVALID_STATE; 368 } 369 370 if (numFrames < 0) { 371 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 372 } else if (numFrames == 0) { 373 return 0; 374 } 375 376 aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds); 377 378 return result; 379 } 380 381 // ============================================================ 382 // Stream - queries 383 // ============================================================ 384 385 AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) 386 { 387 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 388 return audioStream->getSampleRate(); 389 } 390 391 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) 392 { 393 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 394 return audioStream->getSamplesPerFrame(); 395 } 396 397 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) 398 { 399 return AAudioStream_getChannelCount(stream); 400 } 401 402 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) 403 { 404 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 405 return audioStream->getState(); 406 } 407 408 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) 409 { 410 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 411 return audioStream->getFormat(); 412 } 413 414 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream, 415 int32_t requestedFrames) 416 { 417 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 418 return audioStream->setBufferSize(requestedFrames); 419 } 420 421 AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) 422 { 423 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 424 return audioStream->getBufferSize(); 425 } 426 427 AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) 428 { 429 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 430 return audioStream->getDirection(); 431 } 432 433 AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) 434 { 435 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 436 return audioStream->getFramesPerBurst(); 437 } 438 439 AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) 440 { 441 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 442 return audioStream->getFramesPerDataCallback(); 443 } 444 445 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) 446 { 447 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 448 return audioStream->getBufferCapacity(); 449 } 450 451 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) 452 { 453 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 454 return audioStream->getXRunCount(); 455 } 456 457 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream) 458 { 459 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 460 return audioStream->getPerformanceMode(); 461 } 462 463 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) 464 { 465 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 466 return audioStream->getDeviceId(); 467 } 468 469 AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream) 470 { 471 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 472 return audioStream->getSharingMode(); 473 } 474 475 AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream) 476 { 477 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 478 return audioStream->getUsage(); 479 } 480 481 AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream) 482 { 483 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 484 return audioStream->getContentType(); 485 } 486 487 AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream) 488 { 489 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 490 return audioStream->getInputPreset(); 491 } 492 493 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream) 494 { 495 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 496 return audioStream->getSessionId(); 497 } 498 499 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) 500 { 501 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 502 return audioStream->getFramesWritten(); 503 } 504 505 AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) 506 { 507 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 508 return audioStream->getFramesRead(); 509 } 510 511 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream, 512 clockid_t clockid, 513 int64_t *framePosition, 514 int64_t *timeNanoseconds) 515 { 516 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 517 if (framePosition == nullptr) { 518 return AAUDIO_ERROR_NULL; 519 } else if (timeNanoseconds == nullptr) { 520 return AAUDIO_ERROR_NULL; 521 } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) { 522 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 523 } 524 525 return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds); 526 } 527 528 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() { 529 return s_MMapPolicy; 530 } 531 532 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) { 533 aaudio_result_t result = AAUDIO_OK; 534 switch(policy) { 535 case AAUDIO_UNSPECIFIED: 536 case AAUDIO_POLICY_NEVER: 537 case AAUDIO_POLICY_AUTO: 538 case AAUDIO_POLICY_ALWAYS: 539 s_MMapPolicy = policy; 540 break; 541 default: 542 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 543 break; 544 } 545 return result; 546 } 547 548 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream) 549 { 550 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 551 return audioStream->isMMap(); 552 } 553