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
734 FlushFromAccuracy accuracy, int64_t positionInFrames) {
735 return ResultWithValue<int64_t>(Result::ErrorUnimplemented);
736 }
737
752 virtual oboe::Result setPlaybackParameters(const PlaybackParameters& parameters) {
753 return Result::ErrorUnimplemented;
754 }
755
767
768protected:
769
780 return mErrorCallbackCalled.exchange(true);
781 }
782
789 virtual Result waitForStateTransition(StreamState startingState,
790 StreamState endingState,
791 int64_t timeoutNanoseconds);
792
800 virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) {
801 return DataCallbackResult::Stop;
802 }
803
812 DataCallbackResult fireDataCallback(void *audioData, int numFrames);
813
818 return mDataCallbackEnabled;
819 }
820
825 void setDataCallbackEnabled(bool enabled) {
826 mDataCallbackEnabled = enabled;
827 }
828
834
839 if (mDelayBeforeCloseMillis > 0) {
840 usleep(mDelayBeforeCloseMillis * 1000);
841 }
842 }
843
848
853 virtual void endPerformanceHintInCallback(int32_t /*numFrames*/) {}
854
858 virtual void closePerformanceHint() {}
859
860 /*
861 * Set a weak_ptr to this stream from the shared_ptr so that we can
862 * later use a shared_ptr in the error callback.
863 */
864 void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) {
865 mWeakThis = sharedStream;
866 }
867
868 /*
869 * Make a shared_ptr that will prevent this stream from being deleted.
870 */
871 std::shared_ptr<oboe::AudioStream> lockWeakThis() {
872 return mWeakThis.lock();
873 }
874
875 std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object
876
883 std::atomic<int64_t> mFramesWritten{};
884
891 std::atomic<int64_t> mFramesRead{};
892
893 std::mutex mLock; // for synchronizing start/stop/close
894
895 oboe::Result mErrorCallbackResult = oboe::Result::OK;
896
901 int32_t mFramesPerBurst = kUnspecified;
902
903 // Time to sleep in order to prevent a race condition with a callback after a close().
904 // Two milliseconds may be enough but 10 msec is even safer.
905 static constexpr int kMinDelayBeforeCloseMillis = 10;
906 static constexpr int kMaxDelayBeforeCloseMillis = 100;
907 int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis;
908
909private:
910
911 // Log the scheduler if it changes.
912 void checkScheduler();
913 int mPreviousScheduler = -1;
914
915 std::atomic<bool> mDataCallbackEnabled{false};
916 std::atomic<bool> mErrorCallbackCalled{false};
917
918 std::atomic<bool> mPerformanceHintEnabled{false}; // set only by app
919};
920
926 void operator()(AudioStream *audioStream) {
927 if (audioStream) {
928 audioStream->close();
929 }
930 delete audioStream;
931 }
932 };
933} // namespace oboe
934
935#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:901
virtual Result pause(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
std::atomic< int64_t > mFramesRead
Definition AudioStream.h:891
virtual Result waitForStateChange(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0
virtual DataCallbackResult onDefaultCallback(void *, int)
Definition AudioStream.h:800
void setDataCallbackEnabled(bool enabled)
Definition AudioStream.h:825
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:858
int32_t getBytesPerFrame() const
Definition AudioStream.h:250
void sleepBeforeClose()
Definition AudioStream.h:838
virtual void updateFramesWritten()=0
virtual Result open()
Definition AudioStream.h:66
virtual void beginPerformanceHintInCallback()
Definition AudioStream.h:847
virtual Result requestFlush()=0
virtual void endPerformanceHintInCallback(int32_t)
Definition AudioStream.h:853
virtual Result requestPause()=0
virtual Result requestStop()=0
virtual ResultWithValue< PlaybackParameters > getPlaybackParameters()
Definition AudioStream.h:764
std::atomic< int64_t > mFramesWritten
Definition AudioStream.h:883
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:779
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
virtual oboe::Result setPlaybackParameters(const PlaybackParameters &parameters)
Definition AudioStream.h:752
bool isDataCallbackEnabled()
Definition AudioStream.h:817
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< int64_t > flushFromFrame(FlushFromAccuracy accuracy, int64_t positionInFrames)
Definition AudioStream.h:733
virtual ResultWithValue< FrameTimestamp > getTimestamp(clockid_t)
Definition ResultWithValue.h:47
Definition Definitions.h:1135
Definition AudioStream.h:925