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 
25 #include "utility/AAudioUtilities.h"
26 #include "utility/MonotonicCounter.h"
27 
28 namespace aaudio {
29 
30 typedef void *(*aaudio_audio_thread_proc_t)(void *);
31 
32 class AudioStreamBuilder;
33 
34 /**
35  * AAudio audio stream.
36  */
37 class AudioStream {
38 public:
39 
40     AudioStream();
41 
42     virtual ~AudioStream();
43 
44 
45     // =========== Begin ABSTRACT methods ===========================
46 
47     /* Asynchronous requests.
48      * Use waitForStateChange() to wait for completion.
49      */
50     virtual aaudio_result_t requestStart() = 0;
51     virtual aaudio_result_t requestPause() = 0;
52     virtual aaudio_result_t requestFlush() = 0;
53     virtual aaudio_result_t requestStop() = 0;
54 
55     virtual aaudio_result_t getTimestamp(clockid_t clockId,
56                                        int64_t *framePosition,
57                                        int64_t *timeNanoseconds) = 0;
58 
59 
60     /**
61      * Update state while in the middle of waitForStateChange()
62      * @return
63      */
64     virtual aaudio_result_t updateStateWhileWaiting() = 0;
65 
66 
67     // =========== End ABSTRACT methods ===========================
68 
69     virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
70                                                aaudio_stream_state_t *nextState,
71                                                int64_t timeoutNanoseconds);
72 
73     /**
74      * Open the stream using the parameters in the builder.
75      * Allocate the necessary resources.
76      */
77     virtual aaudio_result_t open(const AudioStreamBuilder& builder);
78 
79     /**
80      * Close the stream and deallocate any resources from the open() call.
81      * It is safe to call close() multiple times.
82      */
close()83     virtual aaudio_result_t close() {
84         return AAUDIO_OK;
85     }
86 
setBufferSize(int32_t requestedFrames)87     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) {
88         return AAUDIO_ERROR_UNIMPLEMENTED;
89     }
90 
91     virtual aaudio_result_t createThread(int64_t periodNanoseconds,
92                                        aaudio_audio_thread_proc_t threadProc,
93                                        void *threadArg);
94 
95     aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds);
96 
registerThread()97     virtual aaudio_result_t registerThread() {
98         return AAUDIO_OK;
99     }
100 
unregisterThread()101     virtual aaudio_result_t unregisterThread() {
102         return AAUDIO_OK;
103     }
104 
105     /**
106      * Internal function used to call the audio thread passed by the user.
107      * It is unfortunately public because it needs to be called by a static 'C' function.
108      */
109     void* wrapUserThread();
110 
111     // ============== Queries ===========================
112 
getState()113     aaudio_stream_state_t getState() const {
114         return mState;
115     }
116 
getBufferSize()117     virtual int32_t getBufferSize() const {
118         return AAUDIO_ERROR_UNIMPLEMENTED;
119     }
120 
getBufferCapacity()121     virtual int32_t getBufferCapacity() const {
122         return AAUDIO_ERROR_UNIMPLEMENTED;
123     }
124 
getFramesPerBurst()125     virtual int32_t getFramesPerBurst() const {
126         return AAUDIO_ERROR_UNIMPLEMENTED;
127     }
128 
getXRunCount()129     virtual int32_t getXRunCount() const {
130         return AAUDIO_ERROR_UNIMPLEMENTED;
131     }
132 
isActive()133     bool isActive() const {
134         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
135     }
136 
isMMap()137     virtual bool isMMap() {
138         return false;
139     }
140 
getSampleRate()141     aaudio_result_t getSampleRate() const {
142         return mSampleRate;
143     }
144 
getFormat()145     aaudio_format_t getFormat()  const {
146         return mFormat;
147     }
148 
getSamplesPerFrame()149     aaudio_result_t getSamplesPerFrame() const {
150         return mSamplesPerFrame;
151     }
152 
getPerformanceMode()153     virtual int32_t getPerformanceMode() const {
154         return mPerformanceMode;
155     }
156 
setPerformanceMode(aaudio_performance_mode_t performanceMode)157     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
158         mPerformanceMode = performanceMode;
159     }
160 
getDeviceId()161     int32_t getDeviceId() const {
162         return mDeviceId;
163     }
164 
getSharingMode()165     aaudio_sharing_mode_t getSharingMode() const {
166         return mSharingMode;
167     }
168 
isSharingModeMatchRequired()169     bool isSharingModeMatchRequired() const {
170         return mSharingModeMatchRequired;
171     }
172 
173     virtual aaudio_direction_t getDirection() const = 0;
174 
175     /**
176      * This is only valid after setSamplesPerFrame() and setFormat() have been called.
177      */
getBytesPerFrame()178     int32_t getBytesPerFrame() const {
179         return mSamplesPerFrame * getBytesPerSample();
180     }
181 
182     /**
183      * This is only valid after setFormat() has been called.
184      */
getBytesPerSample()185     int32_t getBytesPerSample() const {
186         return AAudioConvert_formatToSizeInBytes(mFormat);
187     }
188 
getFramesWritten()189     virtual int64_t getFramesWritten() {
190         return mFramesWritten.get();
191     }
192 
getFramesRead()193     virtual int64_t getFramesRead() {
194         return mFramesRead.get();
195     }
196 
getDataCallbackProc()197     AAudioStream_dataCallback getDataCallbackProc() const {
198         return mDataCallbackProc;
199     }
getErrorCallbackProc()200     AAudioStream_errorCallback getErrorCallbackProc() const {
201         return mErrorCallbackProc;
202     }
203 
getDataCallbackUserData()204     void *getDataCallbackUserData() const {
205         return mDataCallbackUserData;
206     }
getErrorCallbackUserData()207     void *getErrorCallbackUserData() const {
208         return mErrorCallbackUserData;
209     }
210 
getFramesPerDataCallback()211     int32_t getFramesPerDataCallback() const {
212         return mFramesPerDataCallback;
213     }
214 
isDataCallbackActive()215     bool isDataCallbackActive() {
216         return (mDataCallbackProc != nullptr) && isActive();
217     }
218 
219     // ============== I/O ===========================
220     // A Stream will only implement read() or write() depending on its direction.
write(const void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)221     virtual aaudio_result_t write(const void *buffer,
222                              int32_t numFrames,
223                              int64_t timeoutNanoseconds) {
224         return AAUDIO_ERROR_UNIMPLEMENTED;
225     }
226 
read(void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)227     virtual aaudio_result_t read(void *buffer,
228                             int32_t numFrames,
229                             int64_t timeoutNanoseconds) {
230         return AAUDIO_ERROR_UNIMPLEMENTED;
231     }
232 
233 protected:
234 
incrementFramesWritten(int32_t frames)235     virtual int64_t incrementFramesWritten(int32_t frames) {
236         return mFramesWritten.increment(frames);
237     }
238 
incrementFramesRead(int32_t frames)239     virtual int64_t incrementFramesRead(int32_t frames) {
240         return mFramesRead.increment(frames);
241     }
242 
243     /**
244      * This should not be called after the open() call.
245      */
setSampleRate(int32_t sampleRate)246     void setSampleRate(int32_t sampleRate) {
247         mSampleRate = sampleRate;
248     }
249 
250     /**
251      * This should not be called after the open() call.
252      */
setSamplesPerFrame(int32_t samplesPerFrame)253     void setSamplesPerFrame(int32_t samplesPerFrame) {
254         mSamplesPerFrame = samplesPerFrame;
255     }
256 
257     /**
258      * This should not be called after the open() call.
259      */
setSharingMode(aaudio_sharing_mode_t sharingMode)260     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
261         mSharingMode = sharingMode;
262     }
263 
264     /**
265      * This should not be called after the open() call.
266      */
setFormat(aaudio_format_t format)267     void setFormat(aaudio_format_t format) {
268         mFormat = format;
269     }
270 
setState(aaudio_stream_state_t state)271     void setState(aaudio_stream_state_t state) {
272         mState = state;
273     }
274 
setDeviceId(int32_t deviceId)275     void setDeviceId(int32_t deviceId) {
276         mDeviceId = deviceId;
277     }
278 
279     std::mutex           mStreamMutex;
280 
281     std::atomic<bool>    mCallbackEnabled;
282 
283 protected:
284     MonotonicCounter     mFramesWritten;
285     MonotonicCounter     mFramesRead;
286 
setPeriodNanoseconds(int64_t periodNanoseconds)287     void setPeriodNanoseconds(int64_t periodNanoseconds) {
288         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
289     }
290 
getPeriodNanoseconds()291     int64_t getPeriodNanoseconds() {
292         return mPeriodNanoseconds.load(std::memory_order_acquire);
293     }
294 
295 private:
296     // These do not change after open().
297     int32_t                mSamplesPerFrame = AAUDIO_UNSPECIFIED;
298     int32_t                mSampleRate = AAUDIO_UNSPECIFIED;
299     int32_t                mDeviceId = AAUDIO_UNSPECIFIED;
300     aaudio_sharing_mode_t  mSharingMode = AAUDIO_SHARING_MODE_SHARED;
301     bool                   mSharingModeMatchRequired = false; // must match sharing mode requested
302     aaudio_format_t        mFormat = AAUDIO_FORMAT_UNSPECIFIED;
303     aaudio_stream_state_t  mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
304 
305     aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
306 
307     // callback ----------------------------------
308 
309     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
310     void                       *mDataCallbackUserData = nullptr;
311     int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
312 
313     AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
314     void                       *mErrorCallbackUserData = nullptr;
315 
316     // background thread ----------------------------------
317     bool                   mHasThread = false;
318     pthread_t              mThread; // initialized in constructor
319 
320     // These are set by the application thread and then read by the audio pthread.
321     std::atomic<int64_t>   mPeriodNanoseconds; // for tuning SCHED_FIFO threads
322     // TODO make atomic?
323     aaudio_audio_thread_proc_t mThreadProc = nullptr;
324     void*                  mThreadArg = nullptr;
325     aaudio_result_t        mThreadRegistrationResult = AAUDIO_OK;
326 
327 
328 };
329 
330 } /* namespace aaudio */
331 
332 #endif /* AAUDIO_AUDIOSTREAM_H */
333