• 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 <mutex>
22 #include <thread>
23 
24 #include "oboe/AudioStreamBuilder.h"
25 #include "oboe/AudioStream.h"
26 #include "oboe/Definitions.h"
27 #include "AAudioLoader.h"
28 
29 namespace oboe {
30 
31 /**
32  * Implementation of OboeStream that uses AAudio.
33  *
34  * Do not create this class directly.
35  * Use an OboeStreamBuilder to create one.
36  */
37 class AudioStreamAAudio : public AudioStream {
38 public:
39     AudioStreamAAudio();
40     explicit AudioStreamAAudio(const AudioStreamBuilder &builder);
41 
42     virtual ~AudioStreamAAudio() = default;
43 
44     /**
45      *
46      * @return true if AAudio is supported on this device.
47      */
48     static bool isSupported();
49 
50     // These functions override methods in AudioStream.
51     // See AudioStream for documentation.
52     Result open() override;
53     Result close() override;
54 
55     Result requestStart() override;
56     Result requestPause() override;
57     Result requestFlush() override;
58     Result requestStop() override;
59 
60     ResultWithValue<int32_t> write(const void *buffer,
61                   int32_t numFrames,
62                   int64_t timeoutNanoseconds) override;
63 
64     ResultWithValue<int32_t> read(void *buffer,
65                  int32_t numFrames,
66                  int64_t timeoutNanoseconds) override;
67 
68     ResultWithValue<int32_t> setBufferSizeInFrames(int32_t requestedFrames) override;
69     int32_t getBufferSizeInFrames() override;
70     int32_t getFramesPerBurst() override;
71     ResultWithValue<int32_t> getXRunCount() const override;
isXRunCountSupported()72     bool isXRunCountSupported() const override { return true; }
73 
74     ResultWithValue<double> calculateLatencyMillis() override;
75 
76     Result waitForStateChange(StreamState currentState,
77                               StreamState *nextState,
78                               int64_t timeoutNanoseconds) override;
79 
80     Result getTimestamp(clockid_t clockId,
81                                        int64_t *framePosition,
82                                        int64_t *timeNanoseconds) override;
83 
84     StreamState getState() const override;
85 
getAudioApi()86     AudioApi getAudioApi() const override {
87         return AudioApi::AAudio;
88     }
89 
90     DataCallbackResult callOnAudioReady(AAudioStream *stream,
91                                                    void *audioData,
92                                                    int32_t numFrames);
93 
94     bool                 isMMapUsed();
95 
96 protected:
97     static void internalErrorCallback(
98             AAudioStream *stream,
99             void *userData,
100             aaudio_result_t error);
101 
getUnderlyingStream()102     void *getUnderlyingStream() const override {
103         return mAAudioStream.load();
104     }
105 
106     void updateFramesRead() override;
107     void updateFramesWritten() override;
108 
109     void logUnsupportedAttributes();
110 
111 private:
112     // Must call under mLock. And stream must NOT be nullptr.
113     Result requestStop_l(AAudioStream *stream);
114 
115     // Time to sleep in order to prevent a race condition with a callback after a close().
116     // Two milliseconds may be enough but 10 msec is even safer.
117     static constexpr int kDelayBeforeCloseMillis = 10;
118 
119     std::atomic<bool>    mCallbackThreadEnabled;
120 
121     // pointer to the underlying AAudio stream, valid if open, null if closed
122     std::atomic<AAudioStream *> mAAudioStream{nullptr};
123 
124     static AAudioLoader *mLibLoader;
125 };
126 
127 } // namespace oboe
128 
129 #endif // OBOE_STREAM_AAUDIO_H_
130