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 #include <aaudio/AAudio.h> 24 #include <binder/IServiceManager.h> 25 #include <binder/Status.h> 26 #include <utils/StrongPointer.h> 27 28 #include "media/VolumeShaper.h" 29 #include "media/PlayerBase.h" 30 #include "utility/AAudioUtilities.h" 31 #include "utility/MonotonicCounter.h" 32 33 // Cannot get android::media::VolumeShaper to compile! 34 #define AAUDIO_USE_VOLUME_SHAPER 0 35 36 namespace aaudio { 37 38 typedef void *(*aaudio_audio_thread_proc_t)(void *); 39 40 class AudioStreamBuilder; 41 42 constexpr pid_t CALLBACK_THREAD_NONE = 0; 43 44 /** 45 * AAudio audio stream. 46 */ 47 class AudioStream { 48 public: 49 50 AudioStream(); 51 52 virtual ~AudioStream(); 53 54 /** 55 * Lock a mutex and make sure we are not calling from a callback function. 56 * @return result of requestStart(); 57 */ 58 aaudio_result_t safeStart(); 59 60 aaudio_result_t safePause(); 61 62 aaudio_result_t safeFlush(); 63 64 aaudio_result_t safeStop(); 65 66 aaudio_result_t safeClose(); 67 68 // =========== Begin ABSTRACT methods =========================== 69 protected: 70 71 /* Asynchronous requests. 72 * Use waitForStateChange() to wait for completion. 73 */ 74 virtual aaudio_result_t requestStart() = 0; 75 76 /** 77 * Check the state to see if Pause if currently legal. 78 * 79 * @param result pointer to return code 80 * @return true if OK to continue, if false then return result 81 */ 82 bool checkPauseStateTransition(aaudio_result_t *result); 83 isFlushSupported()84 virtual bool isFlushSupported() const { 85 // Only implement FLUSH for OUTPUT streams. 86 return false; 87 } 88 isPauseSupported()89 virtual bool isPauseSupported() const { 90 // Only implement PAUSE for OUTPUT streams. 91 return false; 92 } 93 requestPause()94 virtual aaudio_result_t requestPause() 95 { 96 // Only implement this for OUTPUT streams. 97 return AAUDIO_ERROR_UNIMPLEMENTED; 98 } 99 requestFlush()100 virtual aaudio_result_t requestFlush() { 101 // Only implement this for OUTPUT streams. 102 return AAUDIO_ERROR_UNIMPLEMENTED; 103 } 104 105 virtual aaudio_result_t requestStop() = 0; 106 107 public: 108 virtual aaudio_result_t getTimestamp(clockid_t clockId, 109 int64_t *framePosition, 110 int64_t *timeNanoseconds) = 0; 111 112 113 /** 114 * Update state machine.() 115 * @return 116 */ 117 virtual aaudio_result_t updateStateMachine() = 0; 118 119 // =========== End ABSTRACT methods =========================== 120 121 virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState, 122 aaudio_stream_state_t *nextState, 123 int64_t timeoutNanoseconds); 124 125 /** 126 * Open the stream using the parameters in the builder. 127 * Allocate the necessary resources. 128 */ 129 virtual aaudio_result_t open(const AudioStreamBuilder& builder); 130 131 /** 132 * Close the stream and deallocate any resources from the open() call. 133 * It is safe to call close() multiple times. 134 */ close()135 virtual aaudio_result_t close() { 136 return AAUDIO_OK; 137 } 138 139 virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0; 140 141 virtual aaudio_result_t createThread(int64_t periodNanoseconds, 142 aaudio_audio_thread_proc_t threadProc, 143 void *threadArg); 144 145 aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds); 146 registerThread()147 virtual aaudio_result_t registerThread() { 148 return AAUDIO_OK; 149 } 150 unregisterThread()151 virtual aaudio_result_t unregisterThread() { 152 return AAUDIO_OK; 153 } 154 155 /** 156 * Internal function used to call the audio thread passed by the user. 157 * It is unfortunately public because it needs to be called by a static 'C' function. 158 */ 159 void* wrapUserThread(); 160 161 // ============== Queries =========================== 162 getState()163 aaudio_stream_state_t getState() const { 164 return mState; 165 } 166 getBufferSize()167 virtual int32_t getBufferSize() const { 168 return AAUDIO_ERROR_UNIMPLEMENTED; 169 } 170 getBufferCapacity()171 virtual int32_t getBufferCapacity() const { 172 return AAUDIO_ERROR_UNIMPLEMENTED; 173 } 174 getFramesPerBurst()175 virtual int32_t getFramesPerBurst() const { 176 return AAUDIO_ERROR_UNIMPLEMENTED; 177 } 178 getXRunCount()179 virtual int32_t getXRunCount() const { 180 return AAUDIO_ERROR_UNIMPLEMENTED; 181 } 182 isActive()183 bool isActive() const { 184 return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED; 185 } 186 isMMap()187 virtual bool isMMap() { 188 return false; 189 } 190 getSampleRate()191 aaudio_result_t getSampleRate() const { 192 return mSampleRate; 193 } 194 getFormat()195 aaudio_format_t getFormat() const { 196 return mFormat; 197 } 198 getSamplesPerFrame()199 aaudio_result_t getSamplesPerFrame() const { 200 return mSamplesPerFrame; 201 } 202 getPerformanceMode()203 virtual int32_t getPerformanceMode() const { 204 return mPerformanceMode; 205 } 206 setPerformanceMode(aaudio_performance_mode_t performanceMode)207 void setPerformanceMode(aaudio_performance_mode_t performanceMode) { 208 mPerformanceMode = performanceMode; 209 } 210 getDeviceId()211 int32_t getDeviceId() const { 212 return mDeviceId; 213 } 214 getSharingMode()215 aaudio_sharing_mode_t getSharingMode() const { 216 return mSharingMode; 217 } 218 isSharingModeMatchRequired()219 bool isSharingModeMatchRequired() const { 220 return mSharingModeMatchRequired; 221 } 222 223 virtual aaudio_direction_t getDirection() const = 0; 224 getUsage()225 aaudio_usage_t getUsage() const { 226 return mUsage; 227 } 228 getContentType()229 aaudio_content_type_t getContentType() const { 230 return mContentType; 231 } 232 getInputPreset()233 aaudio_input_preset_t getInputPreset() const { 234 return mInputPreset; 235 } 236 getSessionId()237 int32_t getSessionId() const { 238 return mSessionId; 239 } 240 241 /** 242 * This is only valid after setSamplesPerFrame() and setFormat() have been called. 243 */ getBytesPerFrame()244 int32_t getBytesPerFrame() const { 245 return mSamplesPerFrame * getBytesPerSample(); 246 } 247 248 /** 249 * This is only valid after setFormat() has been called. 250 */ getBytesPerSample()251 int32_t getBytesPerSample() const { 252 return AAudioConvert_formatToSizeInBytes(mFormat); 253 } 254 255 /** 256 * This is only valid after setSamplesPerFrame() and setDeviceFormat() have been called. 257 */ getBytesPerDeviceFrame()258 int32_t getBytesPerDeviceFrame() const { 259 return mSamplesPerFrame * getBytesPerDeviceSample(); 260 } 261 262 /** 263 * This is only valid after setDeviceFormat() has been called. 264 */ getBytesPerDeviceSample()265 int32_t getBytesPerDeviceSample() const { 266 return AAudioConvert_formatToSizeInBytes(getDeviceFormat()); 267 } 268 269 virtual int64_t getFramesWritten() = 0; 270 271 virtual int64_t getFramesRead() = 0; 272 getDataCallbackProc()273 AAudioStream_dataCallback getDataCallbackProc() const { 274 return mDataCallbackProc; 275 } 276 getErrorCallbackProc()277 AAudioStream_errorCallback getErrorCallbackProc() const { 278 return mErrorCallbackProc; 279 } 280 281 aaudio_data_callback_result_t maybeCallDataCallback(void *audioData, int32_t numFrames); 282 283 void maybeCallErrorCallback(aaudio_result_t result); 284 getDataCallbackUserData()285 void *getDataCallbackUserData() const { 286 return mDataCallbackUserData; 287 } 288 getErrorCallbackUserData()289 void *getErrorCallbackUserData() const { 290 return mErrorCallbackUserData; 291 } 292 getFramesPerDataCallback()293 int32_t getFramesPerDataCallback() const { 294 return mFramesPerDataCallback; 295 } 296 297 /** 298 * @return true if data callback has been specified 299 */ isDataCallbackSet()300 bool isDataCallbackSet() const { 301 return mDataCallbackProc != nullptr; 302 } 303 304 /** 305 * @return true if data callback has been specified and stream is running 306 */ isDataCallbackActive()307 bool isDataCallbackActive() const { 308 return isDataCallbackSet() && isActive(); 309 } 310 311 /** 312 * @return true if called from the same thread as the callback 313 */ 314 bool collidesWithCallback() const; 315 316 // ============== I/O =========================== 317 // 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)318 virtual aaudio_result_t write(const void *buffer __unused, 319 int32_t numFrames __unused, 320 int64_t timeoutNanoseconds __unused) { 321 return AAUDIO_ERROR_UNIMPLEMENTED; 322 } 323 read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)324 virtual aaudio_result_t read(void *buffer __unused, 325 int32_t numFrames __unused, 326 int64_t timeoutNanoseconds __unused) { 327 return AAUDIO_ERROR_UNIMPLEMENTED; 328 } 329 330 // This is used by the AudioManager to duck and mute the stream when changing audio focus. 331 void setDuckAndMuteVolume(float duckAndMuteVolume); 332 getDuckAndMuteVolume()333 float getDuckAndMuteVolume() const { 334 return mDuckAndMuteVolume; 335 } 336 337 // Implement this in the output subclasses. doSetVolume()338 virtual android::status_t doSetVolume() { return android::NO_ERROR; } 339 340 #if AAUDIO_USE_VOLUME_SHAPER 341 virtual ::android::binder::Status applyVolumeShaper( 342 const ::android::media::VolumeShaper::Configuration& configuration __unused, 343 const ::android::media::VolumeShaper::Operation& operation __unused); 344 #endif 345 346 /** 347 * Register this stream's PlayerBase with the AudioManager if needed. 348 * Only register output streams. 349 * This should only be called for client streams and not for streams 350 * that run in the service. 351 */ registerPlayerBase()352 void registerPlayerBase() { 353 if (getDirection() == AAUDIO_DIRECTION_OUTPUT) { 354 mPlayerBase->registerWithAudioManager(); 355 } 356 } 357 358 /** 359 * Unregister this stream's PlayerBase with the AudioManager. 360 * This will only unregister if already registered. 361 */ unregisterPlayerBase()362 void unregisterPlayerBase() { 363 mPlayerBase->unregisterWithAudioManager(); 364 } 365 366 // Pass start request through PlayerBase for tracking. systemStart()367 aaudio_result_t systemStart() { 368 mPlayerBase->start(); 369 // Pass aaudio_result_t around the PlayerBase interface, which uses status__t. 370 return mPlayerBase->getResult(); 371 } 372 373 // Pass pause request through PlayerBase for tracking. systemPause()374 aaudio_result_t systemPause() { 375 mPlayerBase->pause(); 376 return mPlayerBase->getResult(); 377 } 378 379 // Pass stop request through PlayerBase for tracking. systemStop()380 aaudio_result_t systemStop() { 381 mPlayerBase->stop(); 382 return mPlayerBase->getResult(); 383 } 384 385 protected: 386 387 // PlayerBase allows the system to control the stream. 388 // Calling through PlayerBase->start() notifies the AudioManager of the player state. 389 // The AudioManager also can start/stop a stream by calling mPlayerBase->playerStart(). 390 // systemStart() ==> mPlayerBase->start() mPlayerBase->playerStart() ==> requestStart() 391 // \ / 392 // ------ AudioManager ------- 393 class MyPlayerBase : public android::PlayerBase { 394 public: 395 explicit MyPlayerBase(AudioStream *parent); 396 397 virtual ~MyPlayerBase(); 398 399 /** 400 * Register for volume changes and remote control. 401 */ 402 void registerWithAudioManager(); 403 404 /** 405 * UnRegister. 406 */ 407 void unregisterWithAudioManager(); 408 409 /** 410 * Just calls unregisterWithAudioManager(). 411 */ 412 void destroy() override; 413 clearParentReference()414 void clearParentReference() { mParent = nullptr; } 415 playerStart()416 android::status_t playerStart() override { 417 // mParent should NOT be null. So go ahead and crash if it is. 418 mResult = mParent->safeStart(); 419 return AAudioConvert_aaudioToAndroidStatus(mResult); 420 } 421 playerPause()422 android::status_t playerPause() override { 423 mResult = mParent->safePause(); 424 return AAudioConvert_aaudioToAndroidStatus(mResult); 425 } 426 playerStop()427 android::status_t playerStop() override { 428 mResult = mParent->safeStop(); 429 return AAudioConvert_aaudioToAndroidStatus(mResult); 430 } 431 playerSetVolume()432 android::status_t playerSetVolume() override { 433 // No pan and only left volume is taken into account from IPLayer interface 434 mParent->setDuckAndMuteVolume(mVolumeMultiplierL /* * mPanMultiplierL */); 435 return android::NO_ERROR; 436 } 437 438 #if AAUDIO_USE_VOLUME_SHAPER applyVolumeShaper(const::android::media::VolumeShaper::Configuration & configuration,const::android::media::VolumeShaper::Operation & operation)439 ::android::binder::Status applyVolumeShaper( 440 const ::android::media::VolumeShaper::Configuration& configuration, 441 const ::android::media::VolumeShaper::Operation& operation) { 442 return mParent->applyVolumeShaper(configuration, operation); 443 } 444 #endif 445 getResult()446 aaudio_result_t getResult() { 447 return mResult; 448 } 449 450 private: 451 AudioStream *mParent; 452 aaudio_result_t mResult = AAUDIO_OK; 453 bool mRegistered = false; 454 }; 455 456 /** 457 * This should not be called after the open() call. 458 * TODO for multiple setters: assert(mState == AAUDIO_STREAM_STATE_UNINITIALIZED) 459 */ setSampleRate(int32_t sampleRate)460 void setSampleRate(int32_t sampleRate) { 461 mSampleRate = sampleRate; 462 } 463 464 /** 465 * This should not be called after the open() call. 466 */ setSamplesPerFrame(int32_t samplesPerFrame)467 void setSamplesPerFrame(int32_t samplesPerFrame) { 468 mSamplesPerFrame = samplesPerFrame; 469 } 470 471 /** 472 * This should not be called after the open() call. 473 */ setSharingMode(aaudio_sharing_mode_t sharingMode)474 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 475 mSharingMode = sharingMode; 476 } 477 478 /** 479 * This should not be called after the open() call. 480 */ setFormat(aaudio_format_t format)481 void setFormat(aaudio_format_t format) { 482 mFormat = format; 483 } 484 485 /** 486 * This should not be called after the open() call. 487 */ setDeviceFormat(aaudio_format_t format)488 void setDeviceFormat(aaudio_format_t format) { 489 mDeviceFormat = format; 490 } 491 getDeviceFormat()492 aaudio_format_t getDeviceFormat() const { 493 return mDeviceFormat; 494 } 495 496 void setState(aaudio_stream_state_t state); 497 setDeviceId(int32_t deviceId)498 void setDeviceId(int32_t deviceId) { 499 mDeviceId = deviceId; 500 } 501 setSessionId(int32_t sessionId)502 void setSessionId(int32_t sessionId) { 503 mSessionId = sessionId; 504 } 505 506 std::atomic<bool> mCallbackEnabled{false}; 507 508 float mDuckAndMuteVolume = 1.0f; 509 510 protected: 511 512 /** 513 * Either convert the data from device format to app format and return a pointer 514 * to the conversion buffer, 515 * OR just pass back the original pointer. 516 * 517 * Note that this is only used for the INPUT path. 518 * 519 * @param audioData 520 * @param numFrames 521 * @return original pointer or the conversion buffer 522 */ maybeConvertDeviceData(const void * audioData,int32_t numFrames)523 virtual const void * maybeConvertDeviceData(const void *audioData, int32_t numFrames) { 524 return audioData; 525 } 526 setPeriodNanoseconds(int64_t periodNanoseconds)527 void setPeriodNanoseconds(int64_t periodNanoseconds) { 528 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 529 } 530 getPeriodNanoseconds()531 int64_t getPeriodNanoseconds() { 532 return mPeriodNanoseconds.load(std::memory_order_acquire); 533 } 534 535 /** 536 * This should not be called after the open() call. 537 */ setUsage(aaudio_usage_t usage)538 void setUsage(aaudio_usage_t usage) { 539 mUsage = usage; 540 } 541 542 /** 543 * This should not be called after the open() call. 544 */ setContentType(aaudio_content_type_t contentType)545 void setContentType(aaudio_content_type_t contentType) { 546 mContentType = contentType; 547 } 548 549 /** 550 * This should not be called after the open() call. 551 */ setInputPreset(aaudio_input_preset_t inputPreset)552 void setInputPreset(aaudio_input_preset_t inputPreset) { 553 mInputPreset = inputPreset; 554 } 555 556 private: 557 558 std::mutex mStreamLock; 559 560 const android::sp<MyPlayerBase> mPlayerBase; 561 562 // These do not change after open(). 563 int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED; 564 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 565 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 566 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 567 bool mSharingModeMatchRequired = false; // must match sharing mode requested 568 aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED; 569 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 570 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE; 571 572 aaudio_usage_t mUsage = AAUDIO_UNSPECIFIED; 573 aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED; 574 aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED; 575 576 int32_t mSessionId = AAUDIO_UNSPECIFIED; 577 578 // Sometimes the hardware is operating with a different format from the app. 579 // Then we require conversion in AAudio. 580 aaudio_format_t mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED; 581 582 // callback ---------------------------------- 583 584 AAudioStream_dataCallback mDataCallbackProc = nullptr; // external callback functions 585 void *mDataCallbackUserData = nullptr; 586 int32_t mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames 587 std::atomic<pid_t> mDataCallbackThread{CALLBACK_THREAD_NONE}; 588 589 AAudioStream_errorCallback mErrorCallbackProc = nullptr; 590 void *mErrorCallbackUserData = nullptr; 591 std::atomic<pid_t> mErrorCallbackThread{CALLBACK_THREAD_NONE}; 592 593 // background thread ---------------------------------- 594 bool mHasThread = false; 595 pthread_t mThread; // initialized in constructor 596 597 // These are set by the application thread and then read by the audio pthread. 598 std::atomic<int64_t> mPeriodNanoseconds; // for tuning SCHED_FIFO threads 599 // TODO make atomic? 600 aaudio_audio_thread_proc_t mThreadProc = nullptr; 601 void *mThreadArg = nullptr; 602 aaudio_result_t mThreadRegistrationResult = AAUDIO_OK; 603 604 }; 605 606 } /* namespace aaudio */ 607 608 #endif /* AAUDIO_AUDIOSTREAM_H */ 609