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 OBOE_STREAM_H_ 18 #define OBOE_STREAM_H_ 19 20 #include <atomic> 21 #include <cstdint> 22 #include <ctime> 23 #include <mutex> 24 #include "oboe/Definitions.h" 25 #include "oboe/ResultWithValue.h" 26 #include "oboe/AudioStreamBuilder.h" 27 #include "oboe/AudioStreamBase.h" 28 29 /** WARNING - UNDER CONSTRUCTION - THIS API WILL CHANGE. */ 30 31 namespace oboe { 32 33 /** 34 * The default number of nanoseconds to wait for when performing state change operations on the 35 * stream, such as `start` and `stop`. 36 * 37 * @see oboe::AudioStream::start 38 */ 39 constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond); 40 41 /** 42 * Base class for Oboe C++ audio stream. 43 */ 44 class AudioStream : public AudioStreamBase { 45 friend class AudioStreamBuilder; // allow access to setWeakThis() and lockWeakThis() 46 public: 47 AudioStream()48 AudioStream() {} 49 50 /** 51 * Construct an `AudioStream` using the given `AudioStreamBuilder` 52 * 53 * @param builder containing all the stream's attributes 54 */ 55 explicit AudioStream(const AudioStreamBuilder &builder); 56 57 virtual ~AudioStream() = default; 58 59 /** 60 * Open a stream based on the current settings. 61 * 62 * Note that we do not recommend re-opening a stream that has been closed. 63 * TODO Should we prevent re-opening? 64 * 65 * @return 66 */ open()67 virtual Result open() { 68 return Result::OK; // Called by subclasses. Might do more in the future. 69 } 70 71 /** 72 * Close the stream and deallocate any resources from the open() call. 73 */ 74 virtual Result close(); 75 76 /** 77 * Start the stream. This will block until the stream has been started, an error occurs 78 * or `timeoutNanoseconds` has been reached. 79 */ 80 virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); 81 82 /** 83 * Pause the stream. This will block until the stream has been paused, an error occurs 84 * or `timeoutNanoseconds` has been reached. 85 */ 86 virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); 87 88 /** 89 * Flush the stream. This will block until the stream has been flushed, an error occurs 90 * or `timeoutNanoseconds` has been reached. 91 */ 92 virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); 93 94 /** 95 * Stop the stream. This will block until the stream has been stopped, an error occurs 96 * or `timeoutNanoseconds` has been reached. 97 */ 98 virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); 99 100 /* Asynchronous requests. 101 * Use waitForStateChange() if you need to wait for completion. 102 */ 103 104 /** 105 * Start the stream asynchronously. Returns immediately (does not block). Equivalent to calling 106 * `start(0)`. 107 */ 108 virtual Result requestStart() = 0; 109 110 /** 111 * Pause the stream asynchronously. Returns immediately (does not block). Equivalent to calling 112 * `pause(0)`. 113 */ 114 virtual Result requestPause() = 0; 115 116 /** 117 * Flush the stream asynchronously. Returns immediately (does not block). Equivalent to calling 118 * `flush(0)`. 119 */ 120 virtual Result requestFlush() = 0; 121 122 /** 123 * Stop the stream asynchronously. Returns immediately (does not block). Equivalent to calling 124 * `stop(0)`. 125 */ 126 virtual Result requestStop() = 0; 127 128 /** 129 * Query the current state, eg. StreamState::Pausing 130 * 131 * @return state or a negative error. 132 */ 133 virtual StreamState getState() = 0; 134 135 /** 136 * Wait until the stream's current state no longer matches the input state. 137 * The input state is passed to avoid race conditions caused by the state 138 * changing between calls. 139 * 140 * Note that generally applications do not need to call this. It is considered 141 * an advanced technique and is mostly used for testing. 142 * 143 * <pre><code> 144 * int64_t timeoutNanos = 500 * kNanosPerMillisecond; // arbitrary 1/2 second 145 * StreamState currentState = stream->getState(); 146 * StreamState nextState = StreamState::Unknown; 147 * while (result == Result::OK && currentState != StreamState::Paused) { 148 * result = stream->waitForStateChange( 149 * currentState, &nextState, timeoutNanos); 150 * currentState = nextState; 151 * } 152 * </code></pre> 153 * 154 * If the state does not change within the timeout period then it will 155 * return ErrorTimeout. This is true even if timeoutNanoseconds is zero. 156 * 157 * @param inputState The state we want to change away from. 158 * @param nextState Pointer to a variable that will be set to the new state. 159 * @param timeoutNanoseconds The maximum time to wait in nanoseconds. 160 * @return Result::OK or a Result::Error. 161 */ 162 virtual Result waitForStateChange(StreamState inputState, 163 StreamState *nextState, 164 int64_t timeoutNanoseconds) = 0; 165 166 /** 167 * This can be used to adjust the latency of the buffer by changing 168 * the threshold where blocking will occur. 169 * By combining this with getXRunCount(), the latency can be tuned 170 * at run-time for each device. 171 * 172 * This cannot be set higher than getBufferCapacity(). 173 * 174 * @param requestedFrames requested number of frames that can be filled without blocking 175 * @return the resulting buffer size in frames (obtained using value()) or an error (obtained 176 * using error()) 177 */ setBufferSizeInFrames(int32_t)178 virtual ResultWithValue<int32_t> setBufferSizeInFrames(int32_t /* requestedFrames */) { 179 return Result::ErrorUnimplemented; 180 } 181 182 /** 183 * An XRun is an Underrun or an Overrun. 184 * During playing, an underrun will occur if the stream is not written in time 185 * and the system runs out of valid data. 186 * During recording, an overrun will occur if the stream is not read in time 187 * and there is no place to put the incoming data so it is discarded. 188 * 189 * An underrun or overrun can cause an audible "pop" or "glitch". 190 * 191 * @return a result which is either Result::OK with the xRun count as the value, or a 192 * Result::Error* code 193 */ getXRunCount()194 virtual ResultWithValue<int32_t> getXRunCount() { 195 return ResultWithValue<int32_t>(Result::ErrorUnimplemented); 196 } 197 198 /** 199 * @return true if XRun counts are supported on the stream 200 */ 201 virtual bool isXRunCountSupported() const = 0; 202 203 /** 204 * Query the number of frames that are read or written by the endpoint at one time. 205 * 206 * @return burst size 207 */ getFramesPerBurst()208 int32_t getFramesPerBurst() const { 209 return mFramesPerBurst; 210 } 211 212 /** 213 * Get the number of bytes in each audio frame. This is calculated using the channel count 214 * and the sample format. For example, a 2 channel floating point stream will have 215 * 2 * 4 = 8 bytes per frame. 216 * 217 * @return number of bytes in each audio frame. 218 */ getBytesPerFrame()219 int32_t getBytesPerFrame() const { return mChannelCount * getBytesPerSample(); } 220 221 /** 222 * Get the number of bytes per sample. This is calculated using the sample format. For example, 223 * a stream using 16-bit integer samples will have 2 bytes per sample. 224 * 225 * @return the number of bytes per sample. 226 */ 227 int32_t getBytesPerSample() const; 228 229 /** 230 * The number of audio frames written into the stream. 231 * This monotonic counter will never get reset. 232 * 233 * @return the number of frames written so far 234 */ 235 virtual int64_t getFramesWritten(); 236 237 /** 238 * The number of audio frames read from the stream. 239 * This monotonic counter will never get reset. 240 * 241 * @return the number of frames read so far 242 */ 243 virtual int64_t getFramesRead(); 244 245 /** 246 * Calculate the latency of a stream based on getTimestamp(). 247 * 248 * Output latency is the time it takes for a given frame to travel from the 249 * app to some type of digital-to-analog converter. If the DAC is external, for example 250 * in a USB interface or a TV connected by HDMI, then there may be additional latency 251 * that the Android device is unaware of. 252 * 253 * Input latency is the time it takes to a given frame to travel from an analog-to-digital 254 * converter (ADC) to the app. 255 * 256 * Note that the latency of an OUTPUT stream will increase abruptly when you write data to it 257 * and then decrease slowly over time as the data is consumed. 258 * 259 * The latency of an INPUT stream will decrease abruptly when you read data from it 260 * and then increase slowly over time as more data arrives. 261 * 262 * The latency of an OUTPUT stream is generally higher than the INPUT latency 263 * because an app generally tries to keep the OUTPUT buffer full and the INPUT buffer empty. 264 * 265 * Note that due to issues in Android before R, we recommend NOT calling 266 * this method from a data callback. See this tech note for more details. 267 * https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md 268 * 269 * @return a ResultWithValue which has a result of Result::OK and a value containing the latency 270 * in milliseconds, or a result of Result::Error*. 271 */ calculateLatencyMillis()272 virtual ResultWithValue<double> calculateLatencyMillis() { 273 return ResultWithValue<double>(Result::ErrorUnimplemented); 274 } 275 276 /** 277 * Get the estimated time that the frame at `framePosition` entered or left the audio processing 278 * pipeline. 279 * 280 * This can be used to coordinate events and interactions with the external environment, and to 281 * estimate the latency of an audio stream. An example of usage can be found in the hello-oboe 282 * sample (search for "calculateCurrentOutputLatencyMillis"). 283 * 284 * The time is based on the implementation's best effort, using whatever knowledge is available 285 * to the system, but cannot account for any delay unknown to the implementation. 286 * 287 * Note that due to issues in Android before R, we recommend NOT calling 288 * this method from a data callback. See this tech note for more details. 289 * https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md 290 * 291 * @deprecated since 1.0, use AudioStream::getTimestamp(clockid_t clockId) instead, which 292 * returns ResultWithValue 293 * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC 294 * @param framePosition the frame number to query 295 * @param timeNanoseconds an output parameter which will contain the presentation timestamp 296 */ getTimestamp(clockid_t,int64_t *,int64_t *)297 virtual Result getTimestamp(clockid_t /* clockId */, 298 int64_t* /* framePosition */, 299 int64_t* /* timeNanoseconds */) { 300 return Result::ErrorUnimplemented; 301 } 302 303 /** 304 * Get the estimated time that the frame at `framePosition` entered or left the audio processing 305 * pipeline. 306 * 307 * This can be used to coordinate events and interactions with the external environment, and to 308 * estimate the latency of an audio stream. An example of usage can be found in the hello-oboe 309 * sample (search for "calculateCurrentOutputLatencyMillis"). 310 * 311 * The time is based on the implementation's best effort, using whatever knowledge is available 312 * to the system, but cannot account for any delay unknown to the implementation. 313 * 314 * Note that due to issues in Android before R, we recommend NOT calling 315 * this method from a data callback. See this tech note for more details. 316 * https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md 317 * 318 * See 319 * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC 320 * @return a FrameTimestamp containing the position and time at which a particular audio frame 321 * entered or left the audio processing pipeline, or an error if the operation failed. 322 */ 323 virtual ResultWithValue<FrameTimestamp> getTimestamp(clockid_t /* clockId */); 324 325 // ============== I/O =========================== 326 /** 327 * Write data from the supplied buffer into the stream. This method will block until the write 328 * is complete or it runs out of time. 329 * 330 * If `timeoutNanoseconds` is zero then this call will not wait. 331 * 332 * @param buffer The address of the first sample. 333 * @param numFrames Number of frames to write. Only complete frames will be written. 334 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion. 335 * @return a ResultWithValue which has a result of Result::OK and a value containing the number 336 * of frames actually written, or result of Result::Error*. 337 */ write(const void *,int32_t,int64_t)338 virtual ResultWithValue<int32_t> write(const void* /* buffer */, 339 int32_t /* numFrames */, 340 int64_t /* timeoutNanoseconds */ ) { 341 return ResultWithValue<int32_t>(Result::ErrorUnimplemented); 342 } 343 344 /** 345 * Read data into the supplied buffer from the stream. This method will block until the read 346 * is complete or it runs out of time. 347 * 348 * If `timeoutNanoseconds` is zero then this call will not wait. 349 * 350 * @param buffer The address of the first sample. 351 * @param numFrames Number of frames to read. Only complete frames will be read. 352 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion. 353 * @return a ResultWithValue which has a result of Result::OK and a value containing the number 354 * of frames actually read, or result of Result::Error*. 355 */ read(void *,int32_t,int64_t)356 virtual ResultWithValue<int32_t> read(void* /* buffer */, 357 int32_t /* numFrames */, 358 int64_t /* timeoutNanoseconds */) { 359 return ResultWithValue<int32_t>(Result::ErrorUnimplemented); 360 } 361 362 /** 363 * Get the underlying audio API which the stream uses. 364 * 365 * @return the API that this stream uses. 366 */ 367 virtual AudioApi getAudioApi() const = 0; 368 369 /** 370 * Returns true if the underlying audio API is AAudio. 371 * 372 * @return true if this stream is implemented using the AAudio API. 373 */ usesAAudio()374 bool usesAAudio() const { 375 return getAudioApi() == AudioApi::AAudio; 376 } 377 378 /** 379 * Only for debugging. Do not use in production. 380 * If you need to call this method something is wrong. 381 * If you think you need it for production then please let us know 382 * so we can modify Oboe so that you don't need this. 383 * 384 * @return nullptr or a pointer to a stream from the system API 385 */ getUnderlyingStream()386 virtual void *getUnderlyingStream() const { 387 return nullptr; 388 } 389 390 /** 391 * Update mFramesWritten. 392 * For internal use only. 393 */ 394 virtual void updateFramesWritten() = 0; 395 396 /** 397 * Update mFramesRead. 398 * For internal use only. 399 */ 400 virtual void updateFramesRead() = 0; 401 402 /* 403 * Swap old callback for new callback. 404 * This not atomic. 405 * This should only be used internally. 406 * @param dataCallback 407 * @return previous dataCallback 408 */ swapDataCallback(AudioStreamDataCallback * dataCallback)409 AudioStreamDataCallback *swapDataCallback(AudioStreamDataCallback *dataCallback) { 410 AudioStreamDataCallback *previousCallback = mDataCallback; 411 mDataCallback = dataCallback; 412 return previousCallback; 413 } 414 415 /* 416 * Swap old callback for new callback. 417 * This not atomic. 418 * This should only be used internally. 419 * @param errorCallback 420 * @return previous errorCallback 421 */ swapErrorCallback(AudioStreamErrorCallback * errorCallback)422 AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) { 423 AudioStreamErrorCallback *previousCallback = mErrorCallback; 424 mErrorCallback = errorCallback; 425 return previousCallback; 426 } 427 428 /** 429 * @return number of frames of data currently in the buffer 430 */ 431 ResultWithValue<int32_t> getAvailableFrames(); 432 433 /** 434 * Wait until the stream has a minimum amount of data available in its buffer. 435 * This can be used with an EXCLUSIVE MMAP input stream to avoid reading data too close to 436 * the DSP write position, which may cause glitches. 437 * 438 * Starting with Oboe 1.7.1, the numFrames will be clipped internally against the 439 * BufferCapacity minus BurstSize. This is to prevent trying to wait for more frames 440 * than could possibly be available. In this case, the return value may be less than numFrames. 441 * Note that there may still be glitching if numFrames is too high. 442 * 443 * @param numFrames requested minimum frames available 444 * @param timeoutNanoseconds 445 * @return number of frames available, ErrorTimeout 446 */ 447 ResultWithValue<int32_t> waitForAvailableFrames(int32_t numFrames, 448 int64_t timeoutNanoseconds); 449 450 /** 451 * @return last result passed from an error callback 452 */ getLastErrorCallbackResult()453 virtual oboe::Result getLastErrorCallbackResult() const { 454 return mErrorCallbackResult; 455 } 456 457 getDelayBeforeCloseMillis()458 int32_t getDelayBeforeCloseMillis() const { 459 return mDelayBeforeCloseMillis; 460 } 461 462 /** 463 * Set the time to sleep before closing the internal stream. 464 * 465 * Sometimes a callback can occur shortly after a stream has been stopped and 466 * even after a close! If the stream has been closed then the callback 467 * might access memory that has been freed, which could cause a crash. 468 * This seems to be more likely in Android P or earlier. 469 * But it can also occur in later versions. By sleeping, we give time for 470 * the callback threads to finish. 471 * 472 * Note that this only has an effect when OboeGlobals::areWorkaroundsEnabled() is true. 473 * 474 * @param delayBeforeCloseMillis time to sleep before close. 475 */ setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis)476 void setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis) { 477 mDelayBeforeCloseMillis = delayBeforeCloseMillis; 478 } 479 480 protected: 481 482 /** 483 * This is used to detect more than one error callback from a stream. 484 * These were bugs in some versions of Android that caused multiple error callbacks. 485 * Internal bug b/63087953 486 * 487 * Calling this sets an atomic<bool> true and returns the previous value. 488 * 489 * @return false on first call, true on subsequent calls 490 */ wasErrorCallbackCalled()491 bool wasErrorCallbackCalled() { 492 return mErrorCallbackCalled.exchange(true); 493 } 494 495 /** 496 * Wait for a transition from one state to another. 497 * @return OK if the endingState was observed, or ErrorUnexpectedState 498 * if any state that was not the startingState or endingState was observed 499 * or ErrorTimeout. 500 */ 501 virtual Result waitForStateTransition(StreamState startingState, 502 StreamState endingState, 503 int64_t timeoutNanoseconds); 504 505 /** 506 * Override this to provide a default for when the application did not specify a callback. 507 * 508 * @param audioData 509 * @param numFrames 510 * @return result 511 */ onDefaultCallback(void *,int)512 virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) { 513 return DataCallbackResult::Stop; 514 } 515 516 /** 517 * Override this to provide your own behaviour for the audio callback 518 * 519 * @param audioData container array which audio frames will be written into or read from 520 * @param numFrames number of frames which were read/written 521 * @return the result of the callback: stop or continue 522 * 523 */ 524 DataCallbackResult fireDataCallback(void *audioData, int numFrames); 525 526 /** 527 * @return true if callbacks may be called 528 */ isDataCallbackEnabled()529 bool isDataCallbackEnabled() { 530 return mDataCallbackEnabled; 531 } 532 533 /** 534 * This can be set false internally to prevent callbacks 535 * after DataCallbackResult::Stop has been returned. 536 */ setDataCallbackEnabled(bool enabled)537 void setDataCallbackEnabled(bool enabled) { 538 mDataCallbackEnabled = enabled; 539 } 540 541 /** 542 * This should only be called as a stream is being opened. 543 * Otherwise we might override setDelayBeforeCloseMillis(). 544 */ 545 void calculateDefaultDelayBeforeCloseMillis(); 546 547 /** 548 * Try to avoid a race condition when closing. 549 */ sleepBeforeClose()550 void sleepBeforeClose() { 551 if (mDelayBeforeCloseMillis > 0) { 552 usleep(mDelayBeforeCloseMillis * 1000); 553 } 554 } 555 556 /* 557 * Set a weak_ptr to this stream from the shared_ptr so that we can 558 * later use a shared_ptr in the error callback. 559 */ setWeakThis(std::shared_ptr<oboe::AudioStream> & sharedStream)560 void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) { 561 mWeakThis = sharedStream; 562 } 563 564 /* 565 * Make a shared_ptr that will prevent this stream from being deleted. 566 */ lockWeakThis()567 std::shared_ptr<oboe::AudioStream> lockWeakThis() { 568 return mWeakThis.lock(); 569 } 570 571 std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object 572 573 /** 574 * Number of frames which have been written into the stream 575 * 576 * This is signed integer to match the counters in AAudio. 577 * At audio rates, the counter will overflow in about six million years. 578 */ 579 std::atomic<int64_t> mFramesWritten{}; 580 581 /** 582 * Number of frames which have been read from the stream. 583 * 584 * This is signed integer to match the counters in AAudio. 585 * At audio rates, the counter will overflow in about six million years. 586 */ 587 std::atomic<int64_t> mFramesRead{}; 588 589 std::mutex mLock; // for synchronizing start/stop/close 590 591 oboe::Result mErrorCallbackResult = oboe::Result::OK; 592 593 /** 594 * Number of frames which will be copied to/from the audio device in a single read/write 595 * operation 596 */ 597 int32_t mFramesPerBurst = kUnspecified; 598 599 // Time to sleep in order to prevent a race condition with a callback after a close(). 600 // Two milliseconds may be enough but 10 msec is even safer. 601 static constexpr int kMinDelayBeforeCloseMillis = 10; 602 int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis; 603 604 private: 605 606 // Log the scheduler if it changes. 607 void checkScheduler(); 608 int mPreviousScheduler = -1; 609 610 std::atomic<bool> mDataCallbackEnabled{false}; 611 std::atomic<bool> mErrorCallbackCalled{false}; 612 }; 613 614 /** 615 * This struct is a stateless functor which closes an AudioStream prior to its deletion. 616 * This means it can be used to safely delete a smart pointer referring to an open stream. 617 */ 618 struct StreamDeleterFunctor { operatorStreamDeleterFunctor619 void operator()(AudioStream *audioStream) { 620 if (audioStream) { 621 audioStream->close(); 622 } 623 delete audioStream; 624 } 625 }; 626 } // namespace oboe 627 628 #endif /* OBOE_STREAM_H_ */ 629