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 OBOE_STREAM_AAUDIO_H_ 18 #define OBOE_STREAM_AAUDIO_H_ 19 20 #include <atomic> 21 #include <shared_mutex> 22 #include <mutex> 23 #include <thread> 24 25 #include <common/AdpfWrapper.h> 26 #include "oboe/AudioStreamBuilder.h" 27 #include "oboe/AudioStream.h" 28 #include "oboe/Definitions.h" 29 #include "AAudioLoader.h" 30 31 namespace oboe { 32 33 /** 34 * Implementation of OboeStream that uses AAudio. 35 * 36 * Do not create this class directly. 37 * Use an OboeStreamBuilder to create one. 38 */ 39 class AudioStreamAAudio : public AudioStream { 40 public: 41 AudioStreamAAudio(); 42 explicit AudioStreamAAudio(const AudioStreamBuilder &builder); 43 44 virtual ~AudioStreamAAudio() = default; 45 46 /** 47 * 48 * @return true if AAudio is supported on this device. 49 */ 50 static bool isSupported(); 51 52 // These functions override methods in AudioStream. 53 // See AudioStream for documentation. 54 Result open() override; 55 Result release() override; 56 Result close() override; 57 58 Result requestStart() override; 59 Result requestPause() override; 60 Result requestFlush() override; 61 Result requestStop() override; 62 63 ResultWithValue<int32_t> write(const void *buffer, 64 int32_t numFrames, 65 int64_t timeoutNanoseconds) override; 66 67 ResultWithValue<int32_t> read(void *buffer, 68 int32_t numFrames, 69 int64_t timeoutNanoseconds) override; 70 71 ResultWithValue<int32_t> setBufferSizeInFrames(int32_t requestedFrames) override; 72 int32_t getBufferSizeInFrames() override; 73 ResultWithValue<int32_t> getXRunCount() override; isXRunCountSupported()74 bool isXRunCountSupported() const override { return true; } 75 76 ResultWithValue<double> calculateLatencyMillis() override; 77 78 Result waitForStateChange(StreamState currentState, 79 StreamState *nextState, 80 int64_t timeoutNanoseconds) override; 81 82 Result getTimestamp(clockid_t clockId, 83 int64_t *framePosition, 84 int64_t *timeNanoseconds) override; 85 86 StreamState getState() override; 87 getAudioApi()88 AudioApi getAudioApi() const override { 89 return AudioApi::AAudio; 90 } 91 92 DataCallbackResult callOnAudioReady(AAudioStream *stream, 93 void *audioData, 94 int32_t numFrames); 95 96 bool isMMapUsed(); 97 closePerformanceHint()98 void closePerformanceHint() override { 99 mAdpfWrapper.close(); 100 mAdpfOpenAttempted = false; 101 } 102 103 protected: 104 static void internalErrorCallback( 105 AAudioStream *stream, 106 void *userData, 107 aaudio_result_t error); 108 getUnderlyingStream()109 void *getUnderlyingStream() const override { 110 return mAAudioStream.load(); 111 } 112 113 void updateFramesRead() override; 114 void updateFramesWritten() override; 115 116 void logUnsupportedAttributes(); 117 118 void beginPerformanceHintInCallback() override; 119 120 void endPerformanceHintInCallback(int32_t numFrames) override; 121 122 // set by callback (or app when idle) 123 std::atomic<bool> mAdpfOpenAttempted{false}; 124 AdpfWrapper mAdpfWrapper; 125 126 private: 127 // Must call under mLock. And stream must NOT be nullptr. 128 Result requestStop_l(AAudioStream *stream); 129 130 /** 131 * Launch a thread that will stop the stream. 132 */ 133 void launchStopThread(); 134 135 private: 136 137 std::atomic<bool> mCallbackThreadEnabled; 138 std::atomic<bool> mStopThreadAllowed{false}; 139 140 // pointer to the underlying 'C' AAudio stream, valid if open, null if closed 141 std::atomic<AAudioStream *> mAAudioStream{nullptr}; 142 std::shared_mutex mAAudioStreamLock; // to protect mAAudioStream while closing 143 144 static AAudioLoader *mLibLoader; 145 146 // We may not use this but it is so small that it is not worth allocating dynamically. 147 AudioStreamErrorCallback mDefaultErrorCallback; 148 }; 149 150 } // namespace oboe 151 152 #endif // OBOE_STREAM_AAUDIO_H_ 153