• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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