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