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 reportWorkload(int32_t appWorkload)103 oboe::Result reportWorkload(int32_t appWorkload) override { 104 if (!isPerformanceHintEnabled()) { 105 return oboe::Result::ErrorInvalidState; 106 } 107 mAdpfWrapper.reportWorkload(appWorkload); 108 return oboe::Result::OK; 109 } 110 111 Result setOffloadDelayPadding(int32_t delayInFrames, int32_t paddingInFrames) override; 112 ResultWithValue<int32_t> getOffloadDelay() override; 113 ResultWithValue<int32_t> getOffloadPadding() override; 114 Result setOffloadEndOfStream() override; 115 116 protected: 117 static void internalErrorCallback( 118 AAudioStream *stream, 119 void *userData, 120 aaudio_result_t error); 121 122 static void internalPresentationEndCallback( 123 AAudioStream *stream, 124 void *userData); 125 getUnderlyingStream()126 void *getUnderlyingStream() const override { 127 return mAAudioStream.load(); 128 } 129 130 void updateFramesRead() override; 131 void updateFramesWritten() override; 132 133 void logUnsupportedAttributes(); 134 135 void beginPerformanceHintInCallback() override; 136 137 void endPerformanceHintInCallback(int32_t numFrames) override; 138 139 // set by callback (or app when idle) 140 std::atomic<bool> mAdpfOpenAttempted{false}; 141 AdpfWrapper mAdpfWrapper; 142 143 private: 144 // Must call under mLock. And stream must NOT be nullptr. 145 Result requestStop_l(AAudioStream *stream); 146 147 /** 148 * Launch a thread that will stop the stream. 149 */ 150 void launchStopThread(); 151 152 private: 153 154 std::atomic<bool> mCallbackThreadEnabled; 155 std::atomic<bool> mStopThreadAllowed{false}; 156 157 // pointer to the underlying 'C' AAudio stream, valid if open, null if closed 158 std::atomic<AAudioStream *> mAAudioStream{nullptr}; 159 std::shared_mutex mAAudioStreamLock; // to protect mAAudioStream while closing 160 161 static AAudioLoader *mLibLoader; 162 163 // We may not use this but it is so small that it is not worth allocating dynamically. 164 AudioStreamErrorCallback mDefaultErrorCallback; 165 }; 166 167 } // namespace oboe 168 169 #endif // OBOE_STREAM_AAUDIO_H_ 170