Oboe
A library for creating real-time audio apps on Android
Loading...
Searching...
No Matches
AudioStream.h
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#include "oboe/Utilities.h"
29
30namespace oboe {
31
38constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond);
39
44 friend class AudioStreamBuilder; // allow access to setWeakThis() and lockWeakThis()
45public:
46
47 AudioStream() {}
48
54 explicit AudioStream(const AudioStreamBuilder &builder);
55
56 virtual ~AudioStream();
57
66 virtual Result open() {
67 return Result::OK; // Called by subclasses. Might do more in the future.
68 }
69
89 virtual Result release() {
90 return Result::ErrorUnimplemented;
91 }
92
96 virtual Result close();
97
102 virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
103
108 virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
109
114 virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
115
120 virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
121
122 /* Asynchronous requests.
123 * Use waitForStateChange() if you need to wait for completion.
124 */
125
130 virtual Result requestStart() = 0;
131
136 virtual Result requestPause() = 0;
137
142 virtual Result requestFlush() = 0;
143
148 virtual Result requestStop() = 0;
149
155 virtual StreamState getState() = 0;
156
184 virtual Result waitForStateChange(StreamState inputState,
185 StreamState *nextState,
186 int64_t timeoutNanoseconds) = 0;
187
207 virtual ResultWithValue<int32_t> setBufferSizeInFrames(int32_t /* requestedFrames */) {
208 return Result::ErrorUnimplemented;
209 }
210
224 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
225 }
226
230 virtual bool isXRunCountSupported() const = 0;
231
237 int32_t getFramesPerBurst() const {
238 return mFramesPerBurst;
239 }
240
250 int32_t getBytesPerFrame() const {
251 return isCompressedFormat(mFormat) ? 1 : mChannelCount * getBytesPerSample(); }
252
262 int32_t getBytesPerSample() const;
263
270 virtual int64_t getFramesWritten();
271
278 virtual int64_t getFramesRead();
279
308 return ResultWithValue<double>(Result::ErrorUnimplemented);
309 }
310
332 virtual Result getTimestamp(clockid_t /* clockId */,
333 int64_t* /* framePosition */,
334 int64_t* /* timeNanoseconds */) {
335 return Result::ErrorUnimplemented;
336 }
337
358 virtual ResultWithValue<FrameTimestamp> getTimestamp(clockid_t /* clockId */);
359
360 // ============== I/O ===========================
373 virtual ResultWithValue<int32_t> write(const void* /* buffer */,
374 int32_t /* numFrames */,
375 int64_t /* timeoutNanoseconds */ ) {
376 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
377 }
378
391 virtual ResultWithValue<int32_t> read(void* /* buffer */,
392 int32_t /* numFrames */,
393 int64_t /* timeoutNanoseconds */) {
394 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
395 }
396
402 virtual AudioApi getAudioApi() const = 0;
403
409 bool usesAAudio() const {
410 return getAudioApi() == AudioApi::AAudio;
411 }
412
421 virtual void *getUnderlyingStream() const {
422 return nullptr;
423 }
424
429 virtual void updateFramesWritten() = 0;
430
435 virtual void updateFramesRead() = 0;
436
437 /*
438 * Swap old callback for new callback.
439 * This not atomic.
440 * This should only be used internally.
441 * @param dataCallback
442 * @return previous dataCallback
443 */
444 AudioStreamDataCallback *swapDataCallback(AudioStreamDataCallback *dataCallback) {
445 AudioStreamDataCallback *previousCallback = mDataCallback;
446 mDataCallback = dataCallback;
447 return previousCallback;
448 }
449
450 /*
451 * Swap old callback for new callback.
452 * This not atomic.
453 * This should only be used internally.
454 * @param errorCallback
455 * @return previous errorCallback
456 */
457 AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) {
458 AudioStreamErrorCallback *previousCallback = mErrorCallback;
459 mErrorCallback = errorCallback;
460 return previousCallback;
461 }
462
467
483 int64_t timeoutNanoseconds);
484
488 virtual oboe::Result getLastErrorCallbackResult() const {
489 return mErrorCallbackResult;
490 }
491
492
493 int32_t getDelayBeforeCloseMillis() const {
494 return mDelayBeforeCloseMillis;
495 }
496
511 void setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis) {
512 mDelayBeforeCloseMillis = delayBeforeCloseMillis;
513 }
514
538 void setPerformanceHintEnabled(bool enabled) {
539 mPerformanceHintEnabled = enabled;
540 }
541
549 return mPerformanceHintEnabled;
550 }
551
578 virtual oboe::Result reportWorkload([[maybe_unused]] int32_t appWorkload) {
579 return oboe::Result::ErrorUnimplemented;
580 }
581
607 virtual oboe::Result notifyWorkloadIncrease([[maybe_unused]] bool cpu,
608 [[maybe_unused]] bool gpu,
609 [[maybe_unused]] const char* debugName) {
610 return oboe::Result::ErrorUnimplemented;
611 }
612
638 virtual oboe::Result notifyWorkloadReset([[maybe_unused]] bool cpu,
639 [[maybe_unused]] bool gpu,
640 [[maybe_unused]] const char* debugName) {
641 return oboe::Result::ErrorUnimplemented;
642 }
643
670 virtual oboe::Result notifyWorkloadSpike([[maybe_unused]] bool cpu,
671 [[maybe_unused]] bool gpu,
672 [[maybe_unused]] const char* debugName) {
673 return oboe::Result::ErrorUnimplemented;
674 }
675
676 virtual oboe::Result setOffloadDelayPadding([[maybe_unused]] int32_t delayInFrames,
677 [[maybe_unused]] int32_t paddingInFrames) {
678 return Result::ErrorUnimplemented;
679 }
680
681 virtual ResultWithValue<int32_t> getOffloadDelay() {
682 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
683 }
684
685 virtual ResultWithValue<int32_t> getOffloadPadding() {
686 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
687 }
688
689 virtual oboe::Result setOffloadEndOfStream() {
690 return Result::ErrorUnimplemented;
691 }
692
693protected:
694
705 return mErrorCallbackCalled.exchange(true);
706 }
707
714 virtual Result waitForStateTransition(StreamState startingState,
715 StreamState endingState,
716 int64_t timeoutNanoseconds);
717
725 virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) {
726 return DataCallbackResult::Stop;
727 }
728
737 DataCallbackResult fireDataCallback(void *audioData, int numFrames);
738
743 return mDataCallbackEnabled;
744 }
745
750 void setDataCallbackEnabled(bool enabled) {
751 mDataCallbackEnabled = enabled;
752 }
753
759
764 if (mDelayBeforeCloseMillis > 0) {
765 usleep(mDelayBeforeCloseMillis * 1000);
766 }
767 }
768
773
778 virtual void endPerformanceHintInCallback(int32_t /*numFrames*/) {}
779
783 virtual void closePerformanceHint() {}
784
785 /*
786 * Set a weak_ptr to this stream from the shared_ptr so that we can
787 * later use a shared_ptr in the error callback.
788 */
789 void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) {
790 mWeakThis = sharedStream;
791 }
792
793 /*
794 * Make a shared_ptr that will prevent this stream from being deleted.
795 */
796 std::shared_ptr<oboe::AudioStream> lockWeakThis() {
797 return mWeakThis.lock();
798 }
799
800 std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object
801
808 std::atomic<int64_t> mFramesWritten{};
809
816 std::atomic<int64_t> mFramesRead{};
817
818 std::mutex mLock; // for synchronizing start/stop/close
819
820 oboe::Result mErrorCallbackResult = oboe::Result::OK;
821
826 int32_t mFramesPerBurst = kUnspecified;
827
828 // Time to sleep in order to prevent a race condition with a callback after a close().
829 // Two milliseconds may be enough but 10 msec is even safer.
830 static constexpr int kMinDelayBeforeCloseMillis = 10;
831 int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis;
832
833private:
834
835 // Log the scheduler if it changes.
836 void checkScheduler();
837 int mPreviousScheduler = -1;
838
839 std::atomic<bool> mDataCallbackEnabled{false};
840 std::atomic<bool> mErrorCallbackCalled{false};
841
842 std::atomic<bool> mPerformanceHintEnabled{false}; // set only by app
843};
844
850 void operator()(AudioStream *audioStream) {
851 if (audioStream) {
852 audioStream->close();
853 }
854 delete audioStream;
855 }
856 };
857} // namespace oboe
858
859#endif /* OBOE_STREAM_H_ */
Definition AudioStreamBase.h:31
int32_t mChannelCount
Definition AudioStreamBase.h:296
AudioStreamDataCallback * mDataCallback
Definition AudioStreamBase.h:284
AudioFormat mFormat
Definition AudioStreamBase.h:309
AudioStreamErrorCallback * mErrorCallback
Definition AudioStreamBase.h:288
Definition AudioStreamBuilder.h:34
Definition AudioStreamCallback.h:34
Definition AudioStreamCallback.h:102
Definition AudioStream.h:43
int32_t mFramesPerBurst
Definition AudioStream.h:826
virtual Result pause(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
std::atomic< int64_t > mFramesRead
Definition AudioStream.h:816
virtual Result waitForStateChange(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0
virtual DataCallbackResult onDefaultCallback(void *, int)
Definition AudioStream.h:725
void setDataCallbackEnabled(bool enabled)
Definition AudioStream.h:750
bool usesAAudio() const
Definition AudioStream.h:409
virtual AudioApi getAudioApi() const =0
int32_t getFramesPerBurst() const
Definition AudioStream.h:237
virtual Result flush(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
virtual oboe::Result notifyWorkloadReset(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:638
virtual Result requestStart()=0
virtual ResultWithValue< double > calculateLatencyMillis()
Definition AudioStream.h:307
virtual ResultWithValue< int32_t > read(void *, int32_t, int64_t)
Definition AudioStream.h:391
virtual bool isXRunCountSupported() const =0
int32_t getBytesPerSample() const
virtual ResultWithValue< int32_t > getXRunCount()
Definition AudioStream.h:223
virtual void updateFramesRead()=0
virtual StreamState getState()=0
virtual Result release()
Definition AudioStream.h:89
virtual oboe::Result notifyWorkloadSpike(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:670
virtual void closePerformanceHint()
Definition AudioStream.h:783
int32_t getBytesPerFrame() const
Definition AudioStream.h:250
void sleepBeforeClose()
Definition AudioStream.h:763
virtual void updateFramesWritten()=0
virtual Result open()
Definition AudioStream.h:66
virtual void beginPerformanceHintInCallback()
Definition AudioStream.h:772
virtual Result requestFlush()=0
virtual void endPerformanceHintInCallback(int32_t)
Definition AudioStream.h:778
virtual Result requestPause()=0
virtual Result requestStop()=0
std::atomic< int64_t > mFramesWritten
Definition AudioStream.h:808
virtual Result waitForStateTransition(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)
virtual void * getUnderlyingStream() const
Definition AudioStream.h:421
AudioStream(const AudioStreamBuilder &builder)
virtual oboe::Result getLastErrorCallbackResult() const
Definition AudioStream.h:488
virtual Result close()
virtual oboe::Result reportWorkload(int32_t appWorkload)
Definition AudioStream.h:578
bool isPerformanceHintEnabled()
Definition AudioStream.h:548
bool wasErrorCallbackCalled()
Definition AudioStream.h:704
ResultWithValue< int32_t > getAvailableFrames()
virtual oboe::Result notifyWorkloadIncrease(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:607
virtual ResultWithValue< int32_t > setBufferSizeInFrames(int32_t)
Definition AudioStream.h:207
virtual int64_t getFramesWritten()
DataCallbackResult fireDataCallback(void *audioData, int numFrames)
ResultWithValue< int32_t > waitForAvailableFrames(int32_t numFrames, int64_t timeoutNanoseconds)
virtual Result getTimestamp(clockid_t, int64_t *, int64_t *)
Definition AudioStream.h:332
virtual ResultWithValue< int32_t > write(const void *, int32_t, int64_t)
Definition AudioStream.h:373
void setPerformanceHintEnabled(bool enabled)
Definition AudioStream.h:538
bool isDataCallbackEnabled()
Definition AudioStream.h:742
virtual Result stop(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
virtual int64_t getFramesRead()
void calculateDefaultDelayBeforeCloseMillis()
virtual Result start(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
void setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis)
Definition AudioStream.h:511
virtual ResultWithValue< FrameTimestamp > getTimestamp(clockid_t)
Definition ResultWithValue.h:47
Definition AudioStream.h:849