AudioStream.h revision 35e80f34a9649752fceafa53e2094cd8eda50a0a
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 <stdint.h> 22#include <aaudio/AAudioDefinitions.h> 23#include <aaudio/AAudio.h> 24 25#include "AAudioUtilities.h" 26#include "MonotonicCounter.h" 27 28namespace aaudio { 29 30class AudioStreamBuilder; 31 32/** 33 * AAudio audio stream. 34 */ 35class AudioStream { 36public: 37 38 AudioStream(); 39 40 virtual ~AudioStream(); 41 42 43 // =========== Begin ABSTRACT methods =========================== 44 45 /* Asynchronous requests. 46 * Use waitForStateChange() to wait for completion. 47 */ 48 virtual aaudio_result_t requestStart() = 0; 49 virtual aaudio_result_t requestPause() = 0; 50 virtual aaudio_result_t requestFlush() = 0; 51 virtual aaudio_result_t requestStop() = 0; 52 53 virtual aaudio_result_t getTimestamp(clockid_t clockId, 54 int64_t *framePosition, 55 int64_t *timeNanoseconds) = 0; 56 57 58 virtual aaudio_result_t updateState() = 0; 59 60 61 // =========== End ABSTRACT methods =========================== 62 63 virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState, 64 aaudio_stream_state_t *nextState, 65 int64_t timeoutNanoseconds); 66 67 /** 68 * Open the stream using the parameters in the builder. 69 * Allocate the necessary resources. 70 */ 71 virtual aaudio_result_t open(const AudioStreamBuilder& builder); 72 73 /** 74 * Close the stream and deallocate any resources from the open() call. 75 * It is safe to call close() multiple times. 76 */ 77 virtual aaudio_result_t close() { 78 return AAUDIO_OK; 79 } 80 81 virtual aaudio_result_t setBufferSize(int32_t requestedFrames) { 82 return AAUDIO_ERROR_UNIMPLEMENTED; 83 } 84 85 virtual aaudio_result_t createThread(int64_t periodNanoseconds, 86 aaudio_audio_thread_proc_t threadProc, 87 void *threadArg); 88 89 virtual aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds); 90 91 virtual aaudio_result_t registerThread() { 92 return AAUDIO_OK; 93 } 94 95 virtual aaudio_result_t unregisterThread() { 96 return AAUDIO_OK; 97 } 98 99 /** 100 * Internal function used to call the audio thread passed by the user. 101 * It is unfortunately public because it needs to be called by a static 'C' function. 102 */ 103 void* wrapUserThread(); 104 105 // ============== Queries =========================== 106 107 aaudio_stream_state_t getState() const { 108 return mState; 109 } 110 111 virtual int32_t getBufferSize() const { 112 return AAUDIO_ERROR_UNIMPLEMENTED; 113 } 114 115 virtual int32_t getBufferCapacity() const { 116 return AAUDIO_ERROR_UNIMPLEMENTED; 117 } 118 119 virtual int32_t getFramesPerBurst() const { 120 return AAUDIO_ERROR_UNIMPLEMENTED; 121 } 122 123 virtual int32_t getXRunCount() const { 124 return AAUDIO_ERROR_UNIMPLEMENTED; 125 } 126 127 bool isPlaying() const { 128 return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED; 129 } 130 131 aaudio_result_t getSampleRate() const { 132 return mSampleRate; 133 } 134 135 aaudio_audio_format_t getFormat() const { 136 return mFormat; 137 } 138 139 aaudio_result_t getSamplesPerFrame() const { 140 return mSamplesPerFrame; 141 } 142 143 int32_t getDeviceId() const { 144 return mDeviceId; 145 } 146 147 aaudio_sharing_mode_t getSharingMode() const { 148 return mSharingMode; 149 } 150 151 aaudio_direction_t getDirection() const { 152 return mDirection; 153 } 154 155 int32_t getBytesPerFrame() const { 156 return mSamplesPerFrame * getBytesPerSample(); 157 } 158 159 int32_t getBytesPerSample() const { 160 return AAudioConvert_formatToSizeInBytes(mFormat); 161 } 162 163 virtual int64_t getFramesWritten() { 164 return mFramesWritten.get(); 165 } 166 167 virtual int64_t getFramesRead() { 168 return mFramesRead.get(); 169 } 170 171 172 // ============== I/O =========================== 173 // A Stream will only implement read() or write() depending on its direction. 174 virtual aaudio_result_t write(const void *buffer, 175 int32_t numFrames, 176 int64_t timeoutNanoseconds) { 177 return AAUDIO_ERROR_UNIMPLEMENTED; 178 } 179 180 virtual aaudio_result_t read(void *buffer, 181 int32_t numFrames, 182 int64_t timeoutNanoseconds) { 183 return AAUDIO_ERROR_UNIMPLEMENTED; 184 } 185 186protected: 187 188 virtual int64_t incrementFramesWritten(int32_t frames) { 189 return static_cast<int64_t>(mFramesWritten.increment(frames)); 190 } 191 192 virtual int64_t incrementFramesRead(int32_t frames) { 193 return static_cast<int64_t>(mFramesRead.increment(frames)); 194 } 195 196 /** 197 * Wait for a transition from one state to another. 198 * @return AAUDIO_OK if the endingState was observed, or AAUDIO_ERROR_UNEXPECTED_STATE 199 * if any state that was not the startingState or endingState was observed 200 * or AAUDIO_ERROR_TIMEOUT 201 */ 202 virtual aaudio_result_t waitForStateTransition(aaudio_stream_state_t startingState, 203 aaudio_stream_state_t endingState, 204 int64_t timeoutNanoseconds); 205 206 /** 207 * This should not be called after the open() call. 208 */ 209 void setSampleRate(int32_t sampleRate) { 210 mSampleRate = sampleRate; 211 } 212 213 /** 214 * This should not be called after the open() call. 215 */ 216 void setSamplesPerFrame(int32_t samplesPerFrame) { 217 mSamplesPerFrame = samplesPerFrame; 218 } 219 220 /** 221 * This should not be called after the open() call. 222 */ 223 void setSharingMode(aaudio_sharing_mode_t sharingMode) { 224 mSharingMode = sharingMode; 225 } 226 227 /** 228 * This should not be called after the open() call. 229 */ 230 void setFormat(aaudio_audio_format_t format) { 231 mFormat = format; 232 } 233 234 void setState(aaudio_stream_state_t state) { 235 mState = state; 236 } 237 238 239 240protected: 241 MonotonicCounter mFramesWritten; 242 MonotonicCounter mFramesRead; 243 244 void setPeriodNanoseconds(int64_t periodNanoseconds) { 245 mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release); 246 } 247 248 int64_t getPeriodNanoseconds() { 249 return mPeriodNanoseconds.load(std::memory_order_acquire); 250 } 251 252private: 253 // These do not change after open(). 254 int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED; 255 int32_t mSampleRate = AAUDIO_UNSPECIFIED; 256 int32_t mDeviceId = AAUDIO_UNSPECIFIED; 257 aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED; 258 aaudio_audio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED; 259 aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT; 260 aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 261 262 // background thread ---------------------------------- 263 bool mHasThread = false; 264 pthread_t mThread; // initialized in constructor 265 266 // These are set by the application thread and then read by the audio pthread. 267 std::atomic<int64_t> mPeriodNanoseconds; // for tuning SCHED_FIFO threads 268 // TODO make atomic? 269 aaudio_audio_thread_proc_t mThreadProc = nullptr; 270 void* mThreadArg = nullptr; 271 aaudio_result_t mThreadRegistrationResult = AAUDIO_OK; 272 273 274}; 275 276} /* namespace aaudio */ 277 278#endif /* AAUDIO_AUDIOSTREAM_H */ 279