AudioStream.h revision e2fbb59e729f6c3cade3b531f6f6411417ccbf40
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 28namespace aaudio { 29 30typedef void *(*aaudio_audio_thread_proc_t)(void *); 31 32class AudioStreamBuilder; 33 34/** 35 * AAudio audio stream. 36 */ 37class AudioStream { 38public: 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 virtual 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 isPlaying() 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_audio_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 aaudio_direction_t getDirection() const { 174 return mDirection; 175 } 176 177 /** 178 * This is only valid after setSamplesPerFrame() and setFormat() have been called. 179 */ 180 int32_t getBytesPerFrame() const { 181 return mSamplesPerFrame * getBytesPerSample(); 182 } 183 184 /** 185 * This is only valid after setFormat() has been called. 186 */ 187 int32_t getBytesPerSample() const { 188 return AAudioConvert_formatToSizeInBytes(mFormat); 189 } 190 191 virtual int64_t getFramesWritten() { 192 return mFramesWritten.get(); 193 } 194 195 virtual int64_t getFramesRead() { 196 return mFramesRead.get(); 197 } 198 199 AAudioStream_dataCallback getDataCallbackProc() const { 200 return mDataCallbackProc; 201 } 202 AAudioStream_errorCallback getErrorCallbackProc() const { 203 return mErrorCallbackProc; 204 } 205 206 void *getDataCallbackUserData() const { 207 return mDataCallbackUserData; 208 } 209 void *getErrorCallbackUserData() const { 210 return mErrorCallbackUserData; 211 } 212 213 int32_t getFramesPerDataCallback() const { 214 return mFramesPerDataCallback; 215 } 216 217 bool isDataCallbackActive() { 218 return (mDataCallbackProc != nullptr) && isPlaying(); 219 } 220 221 // ============== I/O =========================== 222 // A Stream will only implement read() or write() depending on its direction. 223 virtual aaudio_result_t write(const void *buffer, 224 int32_t numFrames, 225 int64_t timeoutNanoseconds) { 226 return AAUDIO_ERROR_UNIMPLEMENTED; 227 } 228 229 virtual aaudio_result_t read(void *buffer, 230 int32_t numFrames, 231 int64_t timeoutNanoseconds) { 232 return AAUDIO_ERROR_UNIMPLEMENTED; 233 } 234 235protected: 236 237 virtual int64_t incrementFramesWritten(int32_t frames) { 238 return mFramesWritten.increment(frames); 239 } 240 241 virtual int64_t incrementFramesRead(int32_t frames) { 242 return mFramesRead.increment(frames); 243 } 244 245 /** 246 * This should not be called after the open() call. 247 */ 248 void setSampleRate(int32_t sampleRate) { 249 mSampleRate = sampleRate; 250 } 251 252 /** 253 * This should not be called after the open() call. 254 */ 255 void setSamplesPerFrame(int32_t samplesPerFrame) { 256 mSamplesPerFrame = samplesPerFrame; 257 } 258 259 /** 260 * This should not be called after the open() call. 261 */ 262 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 263 mSharingMode = sharingMode; 264 } 265 266 /** 267 * This should not be called after the open() call. 268 */ 269 void setFormat(aaudio_audio_format_t format) { 270 mFormat = format; 271 } 272 273 void setState(aaudio_stream_state_t state) { 274 mState = state; 275 } 276 277 void setDeviceId(int32_t deviceId) { 278 mDeviceId = deviceId; 279 } 280 281 std::mutex mStreamMutex; 282 283 std::atomic<bool> mCallbackEnabled; 284 285protected: 286 MonotonicCounter mFramesWritten; 287 MonotonicCounter mFramesRead; 288 289 void setPeriodNanoseconds(int64_t periodNanoseconds) { 290 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 291 } 292 293 int64_t getPeriodNanoseconds() { 294 return mPeriodNanoseconds.load(std::memory_order_acquire); 295 } 296 297private: 298 // These do not change after open(). 299 int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED; 300 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 301 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 302 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 303 bool mSharingModeMatchRequired = false; // must match sharing mode requested 304 aaudio_audio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED; 305 aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT; 306 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 307 308 aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE; 309 310 // callback ---------------------------------- 311 312 AAudioStream_dataCallback mDataCallbackProc = nullptr; // external callback functions 313 void *mDataCallbackUserData = nullptr; 314 int32_t mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames 315 316 AAudioStream_errorCallback mErrorCallbackProc = nullptr; 317 void *mErrorCallbackUserData = nullptr; 318 319 // background thread ---------------------------------- 320 bool mHasThread = false; 321 pthread_t mThread; // initialized in constructor 322 323 // These are set by the application thread and then read by the audio pthread. 324 std::atomic<int64_t> mPeriodNanoseconds; // for tuning SCHED_FIFO threads 325 // TODO make atomic? 326 aaudio_audio_thread_proc_t mThreadProc = nullptr; 327 void* mThreadArg = nullptr; 328 aaudio_result_t mThreadRegistrationResult = AAUDIO_OK; 329 330 331}; 332 333} /* namespace aaudio */ 334 335#endif /* AAUDIO_AUDIOSTREAM_H */ 336