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 */ 83 virtual aaudio_result_t close() { 84 return AAUDIO_OK; 85 } 86 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 97 virtual aaudio_result_t registerThread() { 98 return AAUDIO_OK; 99 } 100 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 113 aaudio_stream_state_t getState() const { 114 return mState; 115 } 116 117 virtual int32_t getBufferSize() const { 118 return AAUDIO_ERROR_UNIMPLEMENTED; 119 } 120 121 virtual int32_t getBufferCapacity() const { 122 return AAUDIO_ERROR_UNIMPLEMENTED; 123 } 124 125 virtual int32_t getFramesPerBurst() const { 126 return AAUDIO_ERROR_UNIMPLEMENTED; 127 } 128 129 virtual int32_t getXRunCount() const { 130 return AAUDIO_ERROR_UNIMPLEMENTED; 131 } 132 133 bool isActive() const { 134 return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED; 135 } 136 137 virtual bool isMMap() { 138 return false; 139 } 140 141 aaudio_result_t getSampleRate() const { 142 return mSampleRate; 143 } 144 145 aaudio_format_t getFormat() const { 146 return mFormat; 147 } 148 149 aaudio_result_t getSamplesPerFrame() const { 150 return mSamplesPerFrame; 151 } 152 153 virtual int32_t getPerformanceMode() const { 154 return mPerformanceMode; 155 } 156 157 void setPerformanceMode(aaudio_performance_mode_t performanceMode) { 158 mPerformanceMode = performanceMode; 159 } 160 161 int32_t getDeviceId() const { 162 return mDeviceId; 163 } 164 165 aaudio_sharing_mode_t getSharingMode() const { 166 return mSharingMode; 167 } 168 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 */ 178 int32_t getBytesPerFrame() const { 179 return mSamplesPerFrame * getBytesPerSample(); 180 } 181 182 /** 183 * This is only valid after setFormat() has been called. 184 */ 185 int32_t getBytesPerSample() const { 186 return AAudioConvert_formatToSizeInBytes(mFormat); 187 } 188 189 virtual int64_t getFramesWritten() { 190 return mFramesWritten.get(); 191 } 192 193 virtual int64_t getFramesRead() { 194 return mFramesRead.get(); 195 } 196 197 AAudioStream_dataCallback getDataCallbackProc() const { 198 return mDataCallbackProc; 199 } 200 AAudioStream_errorCallback getErrorCallbackProc() const { 201 return mErrorCallbackProc; 202 } 203 204 void *getDataCallbackUserData() const { 205 return mDataCallbackUserData; 206 } 207 void *getErrorCallbackUserData() const { 208 return mErrorCallbackUserData; 209 } 210 211 int32_t getFramesPerDataCallback() const { 212 return mFramesPerDataCallback; 213 } 214 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. 221 virtual aaudio_result_t write(const void *buffer, 222 int32_t numFrames, 223 int64_t timeoutNanoseconds) { 224 return AAUDIO_ERROR_UNIMPLEMENTED; 225 } 226 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 235 virtual int64_t incrementFramesWritten(int32_t frames) { 236 return mFramesWritten.increment(frames); 237 } 238 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 */ 246 void setSampleRate(int32_t sampleRate) { 247 mSampleRate = sampleRate; 248 } 249 250 /** 251 * This should not be called after the open() call. 252 */ 253 void setSamplesPerFrame(int32_t samplesPerFrame) { 254 mSamplesPerFrame = samplesPerFrame; 255 } 256 257 /** 258 * This should not be called after the open() call. 259 */ 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 */ 267 void setFormat(aaudio_format_t format) { 268 mFormat = format; 269 } 270 271 void setState(aaudio_stream_state_t state) { 272 mState = state; 273 } 274 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 287 void setPeriodNanoseconds(int64_t periodNanoseconds) { 288 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 289 } 290 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