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 /** 43 * AAudio audio stream. 44 */ 45 class AudioStream { 46 public: 47 48 AudioStream(); 49 50 virtual ~AudioStream(); 51 52 53 // =========== Begin ABSTRACT methods =========================== 54 55 /* Asynchronous requests. 56 * Use waitForStateChange() to wait for completion. 57 */ 58 virtual aaudio_result_t requestStart() = 0; 59 requestPause()60 virtual aaudio_result_t requestPause() 61 { 62 // Only implement this for OUTPUT streams. 63 return AAUDIO_ERROR_UNIMPLEMENTED; 64 } 65 requestFlush()66 virtual aaudio_result_t requestFlush() { 67 // Only implement this for OUTPUT streams. 68 return AAUDIO_ERROR_UNIMPLEMENTED; 69 } 70 71 virtual aaudio_result_t requestStop() = 0; 72 73 virtual aaudio_result_t getTimestamp(clockid_t clockId, 74 int64_t *framePosition, 75 int64_t *timeNanoseconds) = 0; 76 77 78 /** 79 * Update state machine.() 80 * @return 81 */ 82 virtual aaudio_result_t updateStateMachine() = 0; 83 84 85 // =========== End ABSTRACT methods =========================== 86 87 virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState, 88 aaudio_stream_state_t *nextState, 89 int64_t timeoutNanoseconds); 90 91 /** 92 * Open the stream using the parameters in the builder. 93 * Allocate the necessary resources. 94 */ 95 virtual aaudio_result_t open(const AudioStreamBuilder& builder); 96 97 /** 98 * Close the stream and deallocate any resources from the open() call. 99 * It is safe to call close() multiple times. 100 */ close()101 virtual aaudio_result_t close() { 102 return AAUDIO_OK; 103 } 104 105 virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0; 106 107 virtual aaudio_result_t createThread(int64_t periodNanoseconds, 108 aaudio_audio_thread_proc_t threadProc, 109 void *threadArg); 110 111 aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds); 112 registerThread()113 virtual aaudio_result_t registerThread() { 114 return AAUDIO_OK; 115 } 116 unregisterThread()117 virtual aaudio_result_t unregisterThread() { 118 return AAUDIO_OK; 119 } 120 121 /** 122 * Internal function used to call the audio thread passed by the user. 123 * It is unfortunately public because it needs to be called by a static 'C' function. 124 */ 125 void* wrapUserThread(); 126 127 // ============== Queries =========================== 128 getState()129 aaudio_stream_state_t getState() const { 130 return mState; 131 } 132 getBufferSize()133 virtual int32_t getBufferSize() const { 134 return AAUDIO_ERROR_UNIMPLEMENTED; 135 } 136 getBufferCapacity()137 virtual int32_t getBufferCapacity() const { 138 return AAUDIO_ERROR_UNIMPLEMENTED; 139 } 140 getFramesPerBurst()141 virtual int32_t getFramesPerBurst() const { 142 return AAUDIO_ERROR_UNIMPLEMENTED; 143 } 144 getXRunCount()145 virtual int32_t getXRunCount() const { 146 return AAUDIO_ERROR_UNIMPLEMENTED; 147 } 148 isActive()149 bool isActive() const { 150 return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED; 151 } 152 isMMap()153 virtual bool isMMap() { 154 return false; 155 } 156 getSampleRate()157 aaudio_result_t getSampleRate() const { 158 return mSampleRate; 159 } 160 getFormat()161 aaudio_format_t getFormat() const { 162 return mFormat; 163 } 164 getSamplesPerFrame()165 aaudio_result_t getSamplesPerFrame() const { 166 return mSamplesPerFrame; 167 } 168 getPerformanceMode()169 virtual int32_t getPerformanceMode() const { 170 return mPerformanceMode; 171 } 172 setPerformanceMode(aaudio_performance_mode_t performanceMode)173 void setPerformanceMode(aaudio_performance_mode_t performanceMode) { 174 mPerformanceMode = performanceMode; 175 } 176 getDeviceId()177 int32_t getDeviceId() const { 178 return mDeviceId; 179 } 180 getSharingMode()181 aaudio_sharing_mode_t getSharingMode() const { 182 return mSharingMode; 183 } 184 isSharingModeMatchRequired()185 bool isSharingModeMatchRequired() const { 186 return mSharingModeMatchRequired; 187 } 188 189 virtual aaudio_direction_t getDirection() const = 0; 190 191 /** 192 * This is only valid after setSamplesPerFrame() and setFormat() have been called. 193 */ getBytesPerFrame()194 int32_t getBytesPerFrame() const { 195 return mSamplesPerFrame * getBytesPerSample(); 196 } 197 198 /** 199 * This is only valid after setFormat() has been called. 200 */ getBytesPerSample()201 int32_t getBytesPerSample() const { 202 return AAudioConvert_formatToSizeInBytes(mFormat); 203 } 204 205 virtual int64_t getFramesWritten() = 0; 206 207 virtual int64_t getFramesRead() = 0; 208 getDataCallbackProc()209 AAudioStream_dataCallback getDataCallbackProc() const { 210 return mDataCallbackProc; 211 } getErrorCallbackProc()212 AAudioStream_errorCallback getErrorCallbackProc() const { 213 return mErrorCallbackProc; 214 } 215 getDataCallbackUserData()216 void *getDataCallbackUserData() const { 217 return mDataCallbackUserData; 218 } getErrorCallbackUserData()219 void *getErrorCallbackUserData() const { 220 return mErrorCallbackUserData; 221 } 222 getFramesPerDataCallback()223 int32_t getFramesPerDataCallback() const { 224 return mFramesPerDataCallback; 225 } 226 isDataCallbackActive()227 bool isDataCallbackActive() { 228 return (mDataCallbackProc != nullptr) && isActive(); 229 } 230 231 // ============== I/O =========================== 232 // 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)233 virtual aaudio_result_t write(const void *buffer __unused, 234 int32_t numFrames __unused, 235 int64_t timeoutNanoseconds __unused) { 236 return AAUDIO_ERROR_UNIMPLEMENTED; 237 } 238 read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)239 virtual aaudio_result_t read(void *buffer __unused, 240 int32_t numFrames __unused, 241 int64_t timeoutNanoseconds __unused) { 242 return AAUDIO_ERROR_UNIMPLEMENTED; 243 } 244 245 // This is used by the AudioManager to duck and mute the stream when changing audio focus. setDuckAndMuteVolume(float duckAndMuteVolume)246 void setDuckAndMuteVolume(float duckAndMuteVolume) { 247 mDuckAndMuteVolume = duckAndMuteVolume; 248 doSetVolume(); // apply this change 249 } 250 getDuckAndMuteVolume()251 float getDuckAndMuteVolume() { 252 return mDuckAndMuteVolume; 253 } 254 255 // Implement this in the output subclasses. doSetVolume()256 virtual android::status_t doSetVolume() { return android::NO_ERROR; } 257 258 #if AAUDIO_USE_VOLUME_SHAPER 259 virtual ::android::binder::Status applyVolumeShaper( 260 const ::android::media::VolumeShaper::Configuration& configuration __unused, 261 const ::android::media::VolumeShaper::Operation& operation __unused); 262 #endif 263 264 /** 265 * Register this stream's PlayerBase with the AudioManager if needed. 266 * Only register output streams. 267 * This should only be called for client streams and not for streams 268 * that run in the service. 269 */ registerPlayerBase()270 void registerPlayerBase() { 271 if (getDirection() == AAUDIO_DIRECTION_OUTPUT) { 272 mPlayerBase->registerWithAudioManager(); 273 } 274 } 275 276 /** 277 * Unregister this stream's PlayerBase with the AudioManager. 278 * This will only unregister if already registered. 279 */ unregisterPlayerBase()280 void unregisterPlayerBase() { 281 mPlayerBase->unregisterWithAudioManager(); 282 } 283 284 // Pass start request through PlayerBase for tracking. systemStart()285 aaudio_result_t systemStart() { 286 mPlayerBase->start(); 287 // Pass aaudio_result_t around the PlayerBase interface, which uses status__t. 288 return mPlayerBase->getResult(); 289 } 290 systemPause()291 aaudio_result_t systemPause() { 292 mPlayerBase->pause(); 293 return mPlayerBase->getResult(); 294 } 295 systemStop()296 aaudio_result_t systemStop() { 297 mPlayerBase->stop(); 298 return mPlayerBase->getResult(); 299 } 300 301 protected: 302 303 // PlayerBase allows the system to control the stream. 304 // Calling through PlayerBase->start() notifies the AudioManager of the player state. 305 // The AudioManager also can start/stop a stream by calling mPlayerBase->playerStart(). 306 // systemStart() ==> mPlayerBase->start() mPlayerBase->playerStart() ==> requestStart() 307 // \ / 308 // ------ AudioManager ------- 309 class MyPlayerBase : public android::PlayerBase { 310 public: 311 explicit MyPlayerBase(AudioStream *parent); 312 313 virtual ~MyPlayerBase(); 314 315 /** 316 * Register for volume changes and remote control. 317 */ 318 void registerWithAudioManager(); 319 320 /** 321 * UnRegister. 322 */ 323 void unregisterWithAudioManager(); 324 325 /** 326 * Just calls unregisterWithAudioManager(). 327 */ 328 void destroy() override; 329 clearParentReference()330 void clearParentReference() { mParent = nullptr; } 331 playerStart()332 android::status_t playerStart() override { 333 // mParent should NOT be null. So go ahead and crash if it is. 334 mResult = mParent->requestStart(); 335 return AAudioConvert_aaudioToAndroidStatus(mResult); 336 } 337 playerPause()338 android::status_t playerPause() override { 339 mResult = mParent->requestPause(); 340 return AAudioConvert_aaudioToAndroidStatus(mResult); 341 } 342 playerStop()343 android::status_t playerStop() override { 344 mResult = mParent->requestStop(); 345 return AAudioConvert_aaudioToAndroidStatus(mResult); 346 } 347 playerSetVolume()348 android::status_t playerSetVolume() override { 349 // No pan and only left volume is taken into account from IPLayer interface 350 mParent->setDuckAndMuteVolume(mVolumeMultiplierL /* * mPanMultiplierL */); 351 return android::NO_ERROR; 352 } 353 354 #if AAUDIO_USE_VOLUME_SHAPER applyVolumeShaper(const::android::media::VolumeShaper::Configuration & configuration,const::android::media::VolumeShaper::Operation & operation)355 ::android::binder::Status applyVolumeShaper( 356 const ::android::media::VolumeShaper::Configuration& configuration, 357 const ::android::media::VolumeShaper::Operation& operation) { 358 return mParent->applyVolumeShaper(configuration, operation); 359 } 360 #endif 361 getResult()362 aaudio_result_t getResult() { 363 return mResult; 364 } 365 366 private: 367 AudioStream *mParent; 368 aaudio_result_t mResult = AAUDIO_OK; 369 bool mRegistered = false; 370 }; 371 372 /** 373 * This should not be called after the open() call. 374 */ setSampleRate(int32_t sampleRate)375 void setSampleRate(int32_t sampleRate) { 376 mSampleRate = sampleRate; 377 } 378 379 /** 380 * This should not be called after the open() call. 381 */ setSamplesPerFrame(int32_t samplesPerFrame)382 void setSamplesPerFrame(int32_t samplesPerFrame) { 383 mSamplesPerFrame = samplesPerFrame; 384 } 385 386 /** 387 * This should not be called after the open() call. 388 */ setSharingMode(aaudio_sharing_mode_t sharingMode)389 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 390 mSharingMode = sharingMode; 391 } 392 393 /** 394 * This should not be called after the open() call. 395 */ setFormat(aaudio_format_t format)396 void setFormat(aaudio_format_t format) { 397 mFormat = format; 398 } 399 setState(aaudio_stream_state_t state)400 void setState(aaudio_stream_state_t state) { 401 mState = state; 402 } 403 setDeviceId(int32_t deviceId)404 void setDeviceId(int32_t deviceId) { 405 mDeviceId = deviceId; 406 } 407 408 std::mutex mStreamMutex; 409 410 std::atomic<bool> mCallbackEnabled{false}; 411 412 float mDuckAndMuteVolume = 1.0f; 413 414 protected: 415 setPeriodNanoseconds(int64_t periodNanoseconds)416 void setPeriodNanoseconds(int64_t periodNanoseconds) { 417 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 418 } 419 getPeriodNanoseconds()420 int64_t getPeriodNanoseconds() { 421 return mPeriodNanoseconds.load(std::memory_order_acquire); 422 } 423 424 private: 425 const android::sp<MyPlayerBase> mPlayerBase; 426 427 // These do not change after open(). 428 int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED; 429 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 430 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 431 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 432 bool mSharingModeMatchRequired = false; // must match sharing mode requested 433 aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED; 434 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 435 436 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE; 437 438 // callback ---------------------------------- 439 440 AAudioStream_dataCallback mDataCallbackProc = nullptr; // external callback functions 441 void *mDataCallbackUserData = nullptr; 442 int32_t mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames 443 444 AAudioStream_errorCallback mErrorCallbackProc = nullptr; 445 void *mErrorCallbackUserData = nullptr; 446 447 // background thread ---------------------------------- 448 bool mHasThread = false; 449 pthread_t mThread; // initialized in constructor 450 451 // These are set by the application thread and then read by the audio pthread. 452 std::atomic<int64_t> mPeriodNanoseconds; // for tuning SCHED_FIFO threads 453 // TODO make atomic? 454 aaudio_audio_thread_proc_t mThreadProc = nullptr; 455 void* mThreadArg = nullptr; 456 aaudio_result_t mThreadRegistrationResult = AAUDIO_OK; 457 458 459 }; 460 461 } /* namespace aaudio */ 462 463 #endif /* AAUDIO_AUDIOSTREAM_H */ 464