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 #ifndef AAUDIO_AUDIOSTREAM_H 18 #define AAUDIO_AUDIOSTREAM_H 19 20 #include <atomic> 21 #include <mutex> 22 #include <stdint.h> 23 24 #include <android-base/thread_annotations.h> 25 #include <binder/IServiceManager.h> 26 #include <binder/Status.h> 27 #include <utils/StrongPointer.h> 28 29 #include <aaudio/AAudio.h> 30 #include <media/AudioSystem.h> 31 #include <media/PlayerBase.h> 32 #include <media/VolumeShaper.h> 33 34 #include "utility/AAudioUtilities.h" 35 #include "utility/MonotonicCounter.h" 36 37 // Cannot get android::media::VolumeShaper to compile! 38 #define AAUDIO_USE_VOLUME_SHAPER 0 39 40 namespace aaudio { 41 42 typedef void *(*aaudio_audio_thread_proc_t)(void *); 43 typedef uint32_t aaudio_stream_id_t; 44 45 class AudioStreamBuilder; 46 47 constexpr pid_t CALLBACK_THREAD_NONE = 0; 48 49 /** 50 * AAudio audio stream. 51 */ 52 // By extending AudioDeviceCallback, we also inherit from RefBase. 53 class AudioStream : public android::AudioSystem::AudioDeviceCallback { 54 public: 55 56 AudioStream(); 57 58 virtual ~AudioStream(); 59 60 protected: 61 62 /** 63 * Check the state to see if Pause is currently legal. 64 * 65 * @param result pointer to return code 66 * @return true if OK to continue, if false then return result 67 */ 68 bool checkPauseStateTransition(aaudio_result_t *result); 69 isFlushSupported()70 virtual bool isFlushSupported() const { 71 // Only implement FLUSH for OUTPUT streams. 72 return false; 73 } 74 isPauseSupported()75 virtual bool isPauseSupported() const { 76 // Only implement PAUSE for OUTPUT streams. 77 return false; 78 } 79 80 /* Asynchronous requests. 81 * Use waitForStateChange() to wait for completion. 82 */ 83 virtual aaudio_result_t requestStart_l() REQUIRES(mStreamLock) = 0; 84 requestPause_l()85 virtual aaudio_result_t requestPause_l() REQUIRES(mStreamLock) { 86 // Only implement this for OUTPUT streams. 87 return AAUDIO_ERROR_UNIMPLEMENTED; 88 } 89 requestFlush_l()90 virtual aaudio_result_t requestFlush_l() REQUIRES(mStreamLock) { 91 // Only implement this for OUTPUT streams. 92 return AAUDIO_ERROR_UNIMPLEMENTED; 93 } 94 95 virtual aaudio_result_t requestStop_l() REQUIRES(mStreamLock) = 0; 96 97 public: 98 virtual aaudio_result_t getTimestamp(clockid_t clockId, 99 int64_t *framePosition, 100 int64_t *timeNanoseconds) = 0; 101 102 /** 103 * Update state machine.() 104 * @return 105 */ 106 virtual aaudio_result_t updateStateMachine() = 0; 107 108 // =========== End ABSTRACT methods =========================== 109 110 virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState, 111 aaudio_stream_state_t *nextState, 112 int64_t timeoutNanoseconds); 113 114 /** 115 * Open the stream using the parameters in the builder. 116 * Allocate the necessary resources. 117 */ 118 virtual aaudio_result_t open(const AudioStreamBuilder& builder); 119 120 // log to MediaMetrics 121 virtual void logOpenActual(); 122 void logReleaseBufferState(); 123 124 /* Note about naming for "release" and "close" related methods. 125 * 126 * These names are intended to match the public AAudio API. 127 * The original AAudio API had an AAudioStream_close() function that 128 * released the hardware and deleted the stream. That made it difficult 129 * because apps want to release the HW ASAP but are not in a rush to delete 130 * the stream object. So in R we added an AAudioStream_release() function 131 * that just released the hardware. 132 * The AAudioStream_close() method releases if needed and then closes. 133 */ 134 135 protected: 136 /** 137 * Free any hardware or system resources from the open() call. 138 * It is safe to call release_l() multiple times. 139 */ release_l()140 virtual aaudio_result_t release_l() REQUIRES(mStreamLock) { 141 setState(AAUDIO_STREAM_STATE_CLOSING); 142 return AAUDIO_OK; 143 } 144 145 /** 146 * Free any resources not already freed by release_l(). 147 * Assume release_l() already called. 148 */ 149 virtual void close_l() REQUIRES(mStreamLock); 150 151 public: 152 // This is only used to identify a stream in the logs without 153 // revealing any pointers. getId()154 aaudio_stream_id_t getId() { 155 return mStreamId; 156 } 157 158 virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0; 159 createThread(int64_t periodNanoseconds,aaudio_audio_thread_proc_t threadProc,void * threadArg)160 aaudio_result_t createThread(int64_t periodNanoseconds, 161 aaudio_audio_thread_proc_t threadProc, 162 void *threadArg) 163 EXCLUDES(mStreamLock) { 164 std::lock_guard<std::mutex> lock(mStreamLock); 165 return createThread_l(periodNanoseconds, threadProc, threadArg); 166 } 167 168 aaudio_result_t joinThread(void **returnArg); 169 registerThread()170 virtual aaudio_result_t registerThread() { 171 return AAUDIO_OK; 172 } 173 unregisterThread()174 virtual aaudio_result_t unregisterThread() { 175 return AAUDIO_OK; 176 } 177 178 /** 179 * Internal function used to call the audio thread passed by the user. 180 * It is unfortunately public because it needs to be called by a static 'C' function. 181 */ 182 void* wrapUserThread(); 183 184 // ============== Queries =========================== 185 getState()186 aaudio_stream_state_t getState() const { 187 return mState; 188 } 189 getBufferSize()190 virtual int32_t getBufferSize() const { 191 return AAUDIO_ERROR_UNIMPLEMENTED; 192 } 193 getBufferCapacity()194 virtual int32_t getBufferCapacity() const { 195 return mBufferCapacity; 196 } 197 getFramesPerBurst()198 virtual int32_t getFramesPerBurst() const { 199 return mFramesPerBurst; 200 } 201 getXRunCount()202 virtual int32_t getXRunCount() const { 203 return AAUDIO_ERROR_UNIMPLEMENTED; 204 } 205 isActive()206 bool isActive() const { 207 return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED; 208 } 209 isMMap()210 virtual bool isMMap() { 211 return false; 212 } 213 getSampleRate()214 aaudio_result_t getSampleRate() const { 215 return mSampleRate; 216 } 217 getFormat()218 audio_format_t getFormat() const { 219 return mFormat; 220 } 221 getSamplesPerFrame()222 aaudio_result_t getSamplesPerFrame() const { 223 return mSamplesPerFrame; 224 } 225 getPerformanceMode()226 virtual int32_t getPerformanceMode() const { 227 return mPerformanceMode; 228 } 229 setPerformanceMode(aaudio_performance_mode_t performanceMode)230 void setPerformanceMode(aaudio_performance_mode_t performanceMode) { 231 mPerformanceMode = performanceMode; 232 } 233 getDeviceId()234 int32_t getDeviceId() const { 235 return mDeviceId; 236 } 237 getSharingMode()238 aaudio_sharing_mode_t getSharingMode() const { 239 return mSharingMode; 240 } 241 isSharingModeMatchRequired()242 bool isSharingModeMatchRequired() const { 243 return mSharingModeMatchRequired; 244 } 245 246 virtual aaudio_direction_t getDirection() const = 0; 247 getUsage()248 aaudio_usage_t getUsage() const { 249 return mUsage; 250 } 251 getContentType()252 aaudio_content_type_t getContentType() const { 253 return mContentType; 254 } 255 getSpatializationBehavior()256 aaudio_spatialization_behavior_t getSpatializationBehavior() const { 257 return mSpatializationBehavior; 258 } 259 isContentSpatialized()260 bool isContentSpatialized() const { 261 return mIsContentSpatialized; 262 } 263 getInputPreset()264 aaudio_input_preset_t getInputPreset() const { 265 return mInputPreset; 266 } 267 getAllowedCapturePolicy()268 aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const { 269 return mAllowedCapturePolicy; 270 } 271 getSessionId()272 int32_t getSessionId() const { 273 return mSessionId; 274 } 275 isPrivacySensitive()276 bool isPrivacySensitive() const { 277 return mIsPrivacySensitive; 278 } 279 getRequireMonoBlend()280 bool getRequireMonoBlend() const { 281 return mRequireMonoBlend; 282 } 283 getAudioBalance()284 float getAudioBalance() const { 285 return mAudioBalance; 286 } 287 288 /** 289 * This is only valid after setChannelMask() and setFormat() 290 * have been called. 291 */ getBytesPerFrame()292 int32_t getBytesPerFrame() const { 293 return mSamplesPerFrame * getBytesPerSample(); 294 } 295 296 /** 297 * This is only valid after setFormat() has been called. 298 */ getBytesPerSample()299 int32_t getBytesPerSample() const { 300 return audio_bytes_per_sample(mFormat); 301 } 302 303 /** 304 * This is only valid after setChannelMask() and setDeviceFormat() have been called. 305 */ getBytesPerDeviceFrame()306 int32_t getBytesPerDeviceFrame() const { 307 return getSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat()); 308 } 309 310 virtual int64_t getFramesWritten() = 0; 311 312 virtual int64_t getFramesRead() = 0; 313 getDataCallbackProc()314 AAudioStream_dataCallback getDataCallbackProc() const { 315 return mDataCallbackProc; 316 } 317 getErrorCallbackProc()318 AAudioStream_errorCallback getErrorCallbackProc() const { 319 return mErrorCallbackProc; 320 } 321 322 aaudio_data_callback_result_t maybeCallDataCallback(void *audioData, int32_t numFrames); 323 324 void maybeCallErrorCallback(aaudio_result_t result); 325 getDataCallbackUserData()326 void *getDataCallbackUserData() const { 327 return mDataCallbackUserData; 328 } 329 getErrorCallbackUserData()330 void *getErrorCallbackUserData() const { 331 return mErrorCallbackUserData; 332 } 333 getFramesPerDataCallback()334 int32_t getFramesPerDataCallback() const { 335 return mFramesPerDataCallback; 336 } 337 getChannelMask()338 aaudio_channel_mask_t getChannelMask() const { 339 return mChannelMask; 340 } 341 setChannelMask(aaudio_channel_mask_t channelMask)342 void setChannelMask(aaudio_channel_mask_t channelMask) { 343 mChannelMask = channelMask; 344 mSamplesPerFrame = AAudioConvert_channelMaskToCount(channelMask); 345 } 346 347 /** 348 * @return true if data callback has been specified 349 */ isDataCallbackSet()350 bool isDataCallbackSet() const { 351 return mDataCallbackProc != nullptr; 352 } 353 354 /** 355 * @return true if data callback has been specified and stream is running 356 */ isDataCallbackActive()357 bool isDataCallbackActive() const { 358 return isDataCallbackSet() && isActive(); 359 } 360 361 /** 362 * @return true if called from the same thread as the callback 363 */ 364 bool collidesWithCallback() const; 365 366 // Implement AudioDeviceCallback onAudioDeviceUpdate(audio_io_handle_t audioIo,audio_port_handle_t deviceId)367 void onAudioDeviceUpdate(audio_io_handle_t audioIo, 368 audio_port_handle_t deviceId) override {}; 369 370 // ============== I/O =========================== 371 // A Stream will only implement read() or write() depending on its direction. write(const void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)372 virtual aaudio_result_t write(const void *buffer __unused, 373 int32_t numFrames __unused, 374 int64_t timeoutNanoseconds __unused) { 375 return AAUDIO_ERROR_UNIMPLEMENTED; 376 } 377 read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)378 virtual aaudio_result_t read(void *buffer __unused, 379 int32_t numFrames __unused, 380 int64_t timeoutNanoseconds __unused) { 381 return AAUDIO_ERROR_UNIMPLEMENTED; 382 } 383 384 // This is used by the AudioManager to duck and mute the stream when changing audio focus. 385 void setDuckAndMuteVolume(float duckAndMuteVolume); 386 getDuckAndMuteVolume()387 float getDuckAndMuteVolume() const { 388 return mDuckAndMuteVolume; 389 } 390 391 // Implement this in the output subclasses. doSetVolume()392 virtual android::status_t doSetVolume() { return android::NO_ERROR; } 393 394 #if AAUDIO_USE_VOLUME_SHAPER 395 virtual ::android::binder::Status applyVolumeShaper( 396 const ::android::media::VolumeShaper::Configuration& configuration __unused, 397 const ::android::media::VolumeShaper::Operation& operation __unused); 398 #endif 399 400 /** 401 * Register this stream's PlayerBase with the AudioManager if needed. 402 * Only register output streams. 403 * This should only be called for client streams and not for streams 404 * that run in the service. 405 */ registerPlayerBase()406 void registerPlayerBase() { 407 if (getDirection() == AAUDIO_DIRECTION_OUTPUT) { 408 mPlayerBase->registerWithAudioManager(this); 409 } 410 } 411 412 /** 413 * Unregister this stream's PlayerBase with the AudioManager. 414 * This will only unregister if already registered. 415 */ unregisterPlayerBase()416 void unregisterPlayerBase() { 417 mPlayerBase->unregisterWithAudioManager(); 418 } 419 420 aaudio_result_t systemStart(); 421 422 aaudio_result_t systemPause(); 423 424 aaudio_result_t safeFlush(); 425 426 /** 427 * This is called when an app calls AAudioStream_requestStop(); 428 * It prevents calls from a callback. 429 */ 430 aaudio_result_t systemStopFromApp(); 431 432 /** 433 * This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP. 434 */ 435 aaudio_result_t systemStopInternal(); 436 437 /** 438 * Safely RELEASE a stream after taking mStreamLock and checking 439 * to make sure we are not being called from a callback. 440 * @return AAUDIO_OK or a negative error 441 */ 442 aaudio_result_t safeRelease(); 443 444 /** 445 * Safely RELEASE and CLOSE a stream after taking mStreamLock and checking 446 * to make sure we are not being called from a callback. 447 * @return AAUDIO_OK or a negative error 448 */ 449 aaudio_result_t safeReleaseClose(); 450 451 aaudio_result_t safeReleaseCloseInternal(); 452 453 protected: 454 455 // PlayerBase allows the system to control the stream volume. 456 class MyPlayerBase : public android::PlayerBase { 457 public: 458 MyPlayerBase() = default; 459 460 virtual ~MyPlayerBase() = default; 461 462 /** 463 * Register for volume changes and remote control. 464 */ 465 void registerWithAudioManager(const android::sp<AudioStream>& parent); 466 467 /** 468 * UnRegister. 469 */ 470 void unregisterWithAudioManager(); 471 472 /** 473 * Just calls unregisterWithAudioManager(). 474 */ 475 void destroy() override; 476 477 // Just a stub. The ability to start audio through PlayerBase is being deprecated. playerStart()478 android::status_t playerStart() override { 479 return android::NO_ERROR; 480 } 481 482 // Just a stub. The ability to pause audio through PlayerBase is being deprecated. playerPause()483 android::status_t playerPause() override { 484 return android::NO_ERROR; 485 } 486 487 // Just a stub. The ability to stop audio through PlayerBase is being deprecated. playerStop()488 android::status_t playerStop() override { 489 return android::NO_ERROR; 490 } 491 492 android::status_t playerSetVolume() override; 493 494 #if AAUDIO_USE_VOLUME_SHAPER 495 ::android::binder::Status applyVolumeShaper(); 496 #endif 497 getResult()498 aaudio_result_t getResult() { 499 return mResult; 500 } 501 502 // Returns the playerIId if registered, -1 otherwise. getPlayerIId()503 int32_t getPlayerIId() const { 504 return mPIId; 505 } 506 507 private: 508 // Use a weak pointer so the AudioStream can be deleted. 509 std::mutex mParentLock; 510 android::wp<AudioStream> mParent GUARDED_BY(mParentLock); 511 aaudio_result_t mResult = AAUDIO_OK; 512 bool mRegistered = false; 513 }; 514 515 /** 516 * This should not be called after the open() call. 517 * TODO for multiple setters: assert(mState == AAUDIO_STREAM_STATE_UNINITIALIZED) 518 */ setSampleRate(int32_t sampleRate)519 void setSampleRate(int32_t sampleRate) { 520 mSampleRate = sampleRate; 521 } 522 523 // This should not be called after the open() call. setFramesPerBurst(int32_t framesPerBurst)524 void setFramesPerBurst(int32_t framesPerBurst) { 525 mFramesPerBurst = framesPerBurst; 526 } 527 528 // This should not be called after the open() call. setBufferCapacity(int32_t bufferCapacity)529 void setBufferCapacity(int32_t bufferCapacity) { 530 mBufferCapacity = bufferCapacity; 531 } 532 533 // This should not be called after the open() call. setSharingMode(aaudio_sharing_mode_t sharingMode)534 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 535 mSharingMode = sharingMode; 536 } 537 538 // This should not be called after the open() call. setFormat(audio_format_t format)539 void setFormat(audio_format_t format) { 540 mFormat = format; 541 } 542 543 // This should not be called after the open() call. setDeviceFormat(audio_format_t format)544 void setDeviceFormat(audio_format_t format) { 545 mDeviceFormat = format; 546 } 547 getDeviceFormat()548 audio_format_t getDeviceFormat() const { 549 return mDeviceFormat; 550 } 551 552 void setState(aaudio_stream_state_t state); 553 setDeviceId(int32_t deviceId)554 void setDeviceId(int32_t deviceId) { 555 mDeviceId = deviceId; 556 } 557 558 // This should not be called after the open() call. setSessionId(int32_t sessionId)559 void setSessionId(int32_t sessionId) { 560 mSessionId = sessionId; 561 } 562 563 aaudio_result_t createThread_l(int64_t periodNanoseconds, 564 aaudio_audio_thread_proc_t threadProc, 565 void *threadArg) 566 REQUIRES(mStreamLock); 567 568 aaudio_result_t joinThread_l(void **returnArg) REQUIRES(mStreamLock); 569 570 std::atomic<bool> mCallbackEnabled{false}; 571 572 float mDuckAndMuteVolume = 1.0f; 573 574 protected: 575 576 /** 577 * Either convert the data from device format to app format and return a pointer 578 * to the conversion buffer, 579 * OR just pass back the original pointer. 580 * 581 * Note that this is only used for the INPUT path. 582 * 583 * @param audioData 584 * @param numFrames 585 * @return original pointer or the conversion buffer 586 */ maybeConvertDeviceData(const void * audioData,int32_t)587 virtual const void * maybeConvertDeviceData(const void *audioData, int32_t /*numFrames*/) { 588 return audioData; 589 } 590 setPeriodNanoseconds(int64_t periodNanoseconds)591 void setPeriodNanoseconds(int64_t periodNanoseconds) { 592 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 593 } 594 getPeriodNanoseconds()595 int64_t getPeriodNanoseconds() { 596 return mPeriodNanoseconds.load(std::memory_order_acquire); 597 } 598 599 /** 600 * This should not be called after the open() call. 601 */ setUsage(aaudio_usage_t usage)602 void setUsage(aaudio_usage_t usage) { 603 mUsage = usage; 604 } 605 606 /** 607 * This should not be called after the open() call. 608 */ setContentType(aaudio_content_type_t contentType)609 void setContentType(aaudio_content_type_t contentType) { 610 mContentType = contentType; 611 } 612 setSpatializationBehavior(aaudio_spatialization_behavior_t spatializationBehavior)613 void setSpatializationBehavior(aaudio_spatialization_behavior_t spatializationBehavior) { 614 mSpatializationBehavior = spatializationBehavior; 615 } 616 setIsContentSpatialized(bool isContentSpatialized)617 void setIsContentSpatialized(bool isContentSpatialized) { 618 mIsContentSpatialized = isContentSpatialized; 619 } 620 621 /** 622 * This should not be called after the open() call. 623 */ setInputPreset(aaudio_input_preset_t inputPreset)624 void setInputPreset(aaudio_input_preset_t inputPreset) { 625 mInputPreset = inputPreset; 626 } 627 628 /** 629 * This should not be called after the open() call. 630 */ setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy)631 void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) { 632 mAllowedCapturePolicy = policy; 633 } 634 635 /** 636 * This should not be called after the open() call. 637 */ setPrivacySensitive(bool privacySensitive)638 void setPrivacySensitive(bool privacySensitive) { 639 mIsPrivacySensitive = privacySensitive; 640 } 641 642 /** 643 * This should not be called after the open() call. 644 */ setRequireMonoBlend(bool requireMonoBlend)645 void setRequireMonoBlend(bool requireMonoBlend) { 646 mRequireMonoBlend = requireMonoBlend; 647 } 648 649 /** 650 * This should not be called after the open() call. 651 */ setAudioBalance(float audioBalance)652 void setAudioBalance(float audioBalance) { 653 mAudioBalance = audioBalance; 654 } 655 656 std::string mMetricsId; // set once during open() 657 658 std::mutex mStreamLock; 659 660 private: 661 662 aaudio_result_t safeStop_l() REQUIRES(mStreamLock); 663 664 /** 665 * Release then close the stream. 666 */ releaseCloseFinal_l()667 void releaseCloseFinal_l() REQUIRES(mStreamLock) { 668 if (getState() != AAUDIO_STREAM_STATE_CLOSING) { // not already released? 669 // Ignore result and keep closing. 670 (void) release_l(); 671 } 672 close_l(); 673 } 674 675 const android::sp<MyPlayerBase> mPlayerBase; 676 677 // These do not change after open(). 678 int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED; 679 aaudio_channel_mask_t mChannelMask = AAUDIO_UNSPECIFIED; 680 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 681 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 682 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 683 bool mSharingModeMatchRequired = false; // must match sharing mode requested 684 audio_format_t mFormat = AUDIO_FORMAT_DEFAULT; 685 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 686 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE; 687 int32_t mFramesPerBurst = 0; 688 int32_t mBufferCapacity = 0; 689 690 aaudio_usage_t mUsage = AAUDIO_UNSPECIFIED; 691 aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED; 692 aaudio_spatialization_behavior_t mSpatializationBehavior = AAUDIO_UNSPECIFIED; 693 bool mIsContentSpatialized = false; 694 aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED; 695 aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL; 696 bool mIsPrivacySensitive = false; 697 bool mRequireMonoBlend = false; 698 float mAudioBalance = 0; 699 700 int32_t mSessionId = AAUDIO_UNSPECIFIED; 701 702 // Sometimes the hardware is operating with a different format from the app. 703 // Then we require conversion in AAudio. 704 audio_format_t mDeviceFormat = AUDIO_FORMAT_INVALID; 705 706 // callback ---------------------------------- 707 708 AAudioStream_dataCallback mDataCallbackProc = nullptr; // external callback functions 709 void *mDataCallbackUserData = nullptr; 710 int32_t mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames 711 std::atomic<pid_t> mDataCallbackThread{CALLBACK_THREAD_NONE}; 712 713 AAudioStream_errorCallback mErrorCallbackProc = nullptr; 714 void *mErrorCallbackUserData = nullptr; 715 std::atomic<pid_t> mErrorCallbackThread{CALLBACK_THREAD_NONE}; 716 717 // background thread ---------------------------------- 718 // Use mHasThread to prevent joining twice, which has undefined behavior. 719 bool mHasThread GUARDED_BY(mStreamLock) = false; 720 pthread_t mThread GUARDED_BY(mStreamLock) = {}; 721 722 // These are set by the application thread and then read by the audio pthread. 723 std::atomic<int64_t> mPeriodNanoseconds; // for tuning SCHED_FIFO threads 724 // TODO make atomic? 725 aaudio_audio_thread_proc_t mThreadProc = nullptr; 726 void *mThreadArg = nullptr; 727 aaudio_result_t mThreadRegistrationResult = AAUDIO_OK; 728 729 const aaudio_stream_id_t mStreamId; 730 731 }; 732 733 } /* namespace aaudio */ 734 735 #endif /* AAUDIO_AUDIOSTREAM_H */ 736