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
37 bool highPerformanceAudio = false;
38};
39
46constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond);
47
52 friend class AudioStreamBuilder; // allow access to setWeakThis() and lockWeakThis()
53public:
54
55 AudioStream() {}
56
62 explicit AudioStream(const AudioStreamBuilder &builder);
63
64 virtual ~AudioStream();
65
74 virtual Result open() {
75 return Result::OK; // Called by subclasses. Might do more in the future.
76 }
77
97 virtual Result release() {
98 return Result::ErrorUnimplemented;
99 }
100
104 virtual Result close();
105
110 virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
111
116 virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
117
122 virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
123
128 virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
129
130 /* Asynchronous requests.
131 * Use waitForStateChange() if you need to wait for completion.
132 */
133
138 virtual Result requestStart() = 0;
139
144 virtual Result requestPause() = 0;
145
150 virtual Result requestFlush() = 0;
151
156 virtual Result requestStop() = 0;
157
163 virtual StreamState getState() = 0;
164
192 virtual Result waitForStateChange(StreamState inputState,
193 StreamState *nextState,
194 int64_t timeoutNanoseconds) = 0;
195
215 virtual ResultWithValue<int32_t> setBufferSizeInFrames(int32_t /* requestedFrames */) {
216 return Result::ErrorUnimplemented;
217 }
218
232 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
233 }
234
238 virtual bool isXRunCountSupported() const = 0;
239
245 int32_t getFramesPerBurst() const {
246 return mFramesPerBurst;
247 }
248
258 int32_t getBytesPerFrame() const {
259 return isCompressedFormat(mFormat) ? 1 : mChannelCount * getBytesPerSample(); }
260
270 int32_t getBytesPerSample() const;
271
278 virtual int64_t getFramesWritten();
279
286 virtual int64_t getFramesRead();
287
316 return ResultWithValue<double>(Result::ErrorUnimplemented);
317 }
318
340 virtual Result getTimestamp(clockid_t /* clockId */,
341 int64_t* /* framePosition */,
342 int64_t* /* timeNanoseconds */) {
343 return Result::ErrorUnimplemented;
344 }
345
366 virtual ResultWithValue<FrameTimestamp> getTimestamp(clockid_t /* clockId */);
367
368 // ============== I/O ===========================
381 virtual ResultWithValue<int32_t> write(const void* /* buffer */,
382 int32_t /* numFrames */,
383 int64_t /* timeoutNanoseconds */ ) {
384 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
385 }
386
399 virtual ResultWithValue<int32_t> read(void* /* buffer */,
400 int32_t /* numFrames */,
401 int64_t /* timeoutNanoseconds */) {
402 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
403 }
404
410 virtual AudioApi getAudioApi() const = 0;
411
417 bool usesAAudio() const {
418 return getAudioApi() == AudioApi::AAudio;
419 }
420
429 virtual void *getUnderlyingStream() const {
430 return nullptr;
431 }
432
437 virtual void updateFramesWritten() = 0;
438
443 virtual void updateFramesRead() = 0;
444
445 /*
446 * Swap old callback for new callback.
447 * This not atomic.
448 * This should only be used internally.
449 * @param dataCallback
450 * @return previous dataCallback
451 */
452 AudioStreamDataCallback *swapDataCallback(AudioStreamDataCallback *dataCallback) {
453 AudioStreamDataCallback *previousCallback = mDataCallback;
454 mDataCallback = dataCallback;
455 return previousCallback;
456 }
457
458 /*
459 * Swap old partial data callback for new callback.
460 * This not atomic.
461 * This should only be used internally.
462 * @param dataCallback
463 * @return previous dataCallback
464 */
465 AudioStreamPartialDataCallback *swapPartialDataCallback(
466 AudioStreamPartialDataCallback *partialDataCallback) {
467 AudioStreamPartialDataCallback *previousPartialCallback = mPartialDataCallback;
468 mPartialDataCallback = partialDataCallback;
469 return previousPartialCallback;
470 }
471
472 /*
473 * Swap old callback for new callback.
474 * This not atomic.
475 * This should only be used internally.
476 * @param errorCallback
477 * @return previous errorCallback
478 */
479 AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) {
480 AudioStreamErrorCallback *previousCallback = mErrorCallback;
481 mErrorCallback = errorCallback;
482 return previousCallback;
483 }
484
489
505 int64_t timeoutNanoseconds);
506
510 virtual oboe::Result getLastErrorCallbackResult() const {
511 return mErrorCallbackResult;
512 }
513
514
515 int32_t getDelayBeforeCloseMillis() const {
516 return mDelayBeforeCloseMillis;
517 }
518
533 void setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis) {
534 mDelayBeforeCloseMillis = delayBeforeCloseMillis;
535 }
536
560 void setPerformanceHintEnabled(bool enabled) {
561 mPerformanceHintEnabled = enabled;
562 }
563
570 mPerformanceHintConfig = config;
571 }
572
573 PerformanceHintConfig getPerformanceHintConfig() const {
574 return mPerformanceHintConfig;
575 }
576
582 virtual void setReportActualDurationDisabled([[maybe_unused]] bool disabled) {}
583
591 return mPerformanceHintEnabled;
592 }
593
620 virtual oboe::Result reportWorkload([[maybe_unused]] int32_t appWorkload) {
621 return oboe::Result::ErrorUnimplemented;
622 }
623
649 virtual oboe::Result notifyWorkloadIncrease([[maybe_unused]] bool cpu,
650 [[maybe_unused]] bool gpu,
651 [[maybe_unused]] const char* debugName) {
652 return oboe::Result::ErrorUnimplemented;
653 }
654
680 virtual oboe::Result notifyWorkloadReset([[maybe_unused]] bool cpu,
681 [[maybe_unused]] bool gpu,
682 [[maybe_unused]] const char* debugName) {
683 return oboe::Result::ErrorUnimplemented;
684 }
685
712 virtual oboe::Result notifyWorkloadSpike([[maybe_unused]] bool cpu,
713 [[maybe_unused]] bool gpu,
714 [[maybe_unused]] const char* debugName) {
715 return oboe::Result::ErrorUnimplemented;
716 }
717
718 virtual oboe::Result setOffloadDelayPadding([[maybe_unused]] int32_t delayInFrames,
719 [[maybe_unused]] int32_t paddingInFrames) {
720 return Result::ErrorUnimplemented;
721 }
722
723 virtual ResultWithValue<int32_t> getOffloadDelay() {
724 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
725 }
726
727 virtual ResultWithValue<int32_t> getOffloadPadding() {
728 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
729 }
730
731 virtual oboe::Result setOffloadEndOfStream() {
732 return Result::ErrorUnimplemented;
733 }
734
775 virtual ResultWithValue<int64_t> flushFromFrame([[maybe_unused]] FlushFromAccuracy accuracy,
776 [[maybe_unused]] int64_t positionInFrames) {
777 return ResultWithValue<int64_t>(Result::ErrorUnimplemented);
778 }
779
794 virtual oboe::Result setPlaybackParameters(
795 [[maybe_unused]] const PlaybackParameters& parameters) {
796 return Result::ErrorUnimplemented;
797 }
798
810
811 /*
812 * Make a shared_ptr that will prevent this stream from being deleted.
813 */
814 std::shared_ptr<oboe::AudioStream> lockWeakThis() {
815 return mWeakThis.lock();
816 }
817
818protected:
819
830 return mErrorCallbackCalled.exchange(true);
831 }
832
839 virtual Result waitForStateTransition(StreamState startingState,
840 StreamState endingState,
841 int64_t timeoutNanoseconds);
842
850 virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) {
851 return DataCallbackResult::Stop;
852 }
853
862 virtual DataCallbackResult fireDataCallback(void *audioData, int numFrames);
863
871 virtual int32_t firePartialDataCallback(void* audioData, int numFrames);
872
877 return mDataCallbackEnabled;
878 }
879
884 void setDataCallbackEnabled(bool enabled) {
885 mDataCallbackEnabled = enabled;
886 }
887
893
898 if (mDelayBeforeCloseMillis > 0) {
899 usleep(mDelayBeforeCloseMillis * 1000);
900 }
901 }
902
907
912 virtual void endPerformanceHintInCallback(int32_t /*numFrames*/) {}
913
917 virtual void closePerformanceHint() {}
918
919 /*
920 * Set a weak_ptr to this stream from the shared_ptr so that we can
921 * later use a shared_ptr in the error callback.
922 */
923 void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) {
924 mWeakThis = sharedStream;
925 }
926
927 std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object
928 // Performance hint configuration for this stream.
929 PerformanceHintConfig mPerformanceHintConfig;
930
937 std::atomic<int64_t> mFramesWritten{};
938
945 std::atomic<int64_t> mFramesRead{};
946
947 std::mutex mLock; // for synchronizing start/stop/close
948
949 oboe::Result mErrorCallbackResult = oboe::Result::OK;
950
955 int32_t mFramesPerBurst = kUnspecified;
956
957 // Time to sleep in order to prevent a race condition with a callback after a close().
958 // Two milliseconds may be enough but 10 msec is even safer.
959 static constexpr int kMinDelayBeforeCloseMillis = 10;
960 static constexpr int kMaxDelayBeforeCloseMillis = 100;
961 int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis;
962
963private:
964
965 // Log the scheduler if it changes.
966 void checkScheduler();
967 int mPreviousScheduler = -1;
968
969 std::atomic<bool> mDataCallbackEnabled{false};
970 std::atomic<bool> mErrorCallbackCalled{false};
971
972 std::atomic<bool> mPerformanceHintEnabled{false}; // set only by app
973};
974
980 void operator()(AudioStream *audioStream) {
981 if (audioStream) {
982 audioStream->close();
983 }
984 delete audioStream;
985 }
986 };
987} // namespace oboe
988
989#endif /* OBOE_STREAM_H_ */
Definition AudioStreamBase.h:31
int32_t mChannelCount
Definition AudioStreamBase.h:322
AudioStreamDataCallback * mDataCallback
Definition AudioStreamBase.h:306
AudioFormat mFormat
Definition AudioStreamBase.h:335
AudioStreamErrorCallback * mErrorCallback
Definition AudioStreamBase.h:314
AudioStreamPartialDataCallback * mPartialDataCallback
Definition AudioStreamBase.h:310
Definition AudioStreamBuilder.h:34
Definition AudioStreamCallback.h:34
Definition AudioStream.h:51
int32_t mFramesPerBurst
Definition AudioStream.h:955
virtual Result pause(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
std::atomic< int64_t > mFramesRead
Definition AudioStream.h:945
virtual Result waitForStateChange(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0
virtual DataCallbackResult fireDataCallback(void *audioData, int numFrames)
virtual DataCallbackResult onDefaultCallback(void *, int)
Definition AudioStream.h:850
void setDataCallbackEnabled(bool enabled)
Definition AudioStream.h:884
bool usesAAudio() const
Definition AudioStream.h:417
virtual AudioApi getAudioApi() const =0
int32_t getFramesPerBurst() const
Definition AudioStream.h:245
virtual Result flush(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
virtual oboe::Result notifyWorkloadReset(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:680
virtual Result requestStart()=0
virtual ResultWithValue< double > calculateLatencyMillis()
Definition AudioStream.h:315
virtual ResultWithValue< int32_t > read(void *, int32_t, int64_t)
Definition AudioStream.h:399
virtual bool isXRunCountSupported() const =0
int32_t getBytesPerSample() const
virtual ResultWithValue< int32_t > getXRunCount()
Definition AudioStream.h:231
virtual void updateFramesRead()=0
virtual StreamState getState()=0
virtual Result release()
Definition AudioStream.h:97
virtual oboe::Result notifyWorkloadSpike(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:712
virtual void closePerformanceHint()
Definition AudioStream.h:917
int32_t getBytesPerFrame() const
Definition AudioStream.h:258
void sleepBeforeClose()
Definition AudioStream.h:897
virtual void updateFramesWritten()=0
virtual Result open()
Definition AudioStream.h:74
virtual void beginPerformanceHintInCallback()
Definition AudioStream.h:906
virtual Result requestFlush()=0
virtual void setReportActualDurationDisabled(bool disabled)
Definition AudioStream.h:582
virtual void endPerformanceHintInCallback(int32_t)
Definition AudioStream.h:912
virtual Result requestPause()=0
virtual Result requestStop()=0
virtual ResultWithValue< PlaybackParameters > getPlaybackParameters()
Definition AudioStream.h:807
std::atomic< int64_t > mFramesWritten
Definition AudioStream.h:937
virtual Result waitForStateTransition(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)
virtual void * getUnderlyingStream() const
Definition AudioStream.h:429
AudioStream(const AudioStreamBuilder &builder)
virtual oboe::Result getLastErrorCallbackResult() const
Definition AudioStream.h:510
virtual Result close()
virtual oboe::Result reportWorkload(int32_t appWorkload)
Definition AudioStream.h:620
bool isPerformanceHintEnabled()
Definition AudioStream.h:590
virtual int32_t firePartialDataCallback(void *audioData, int numFrames)
bool wasErrorCallbackCalled()
Definition AudioStream.h:829
ResultWithValue< int32_t > getAvailableFrames()
virtual oboe::Result notifyWorkloadIncrease(bool cpu, bool gpu, const char *debugName)
Definition AudioStream.h:649
virtual ResultWithValue< int32_t > setBufferSizeInFrames(int32_t)
Definition AudioStream.h:215
virtual int64_t getFramesWritten()
void setPerformanceHintConfig(const PerformanceHintConfig &config)
Definition AudioStream.h:569
ResultWithValue< int32_t > waitForAvailableFrames(int32_t numFrames, int64_t timeoutNanoseconds)
virtual Result getTimestamp(clockid_t, int64_t *, int64_t *)
Definition AudioStream.h:340
virtual ResultWithValue< int32_t > write(const void *, int32_t, int64_t)
Definition AudioStream.h:381
void setPerformanceHintEnabled(bool enabled)
Definition AudioStream.h:560
virtual oboe::Result setPlaybackParameters(const PlaybackParameters &parameters)
Definition AudioStream.h:794
bool isDataCallbackEnabled()
Definition AudioStream.h:876
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:533
virtual ResultWithValue< int64_t > flushFromFrame(FlushFromAccuracy accuracy, int64_t positionInFrames)
Definition AudioStream.h:775
virtual ResultWithValue< FrameTimestamp > getTimestamp(clockid_t)
Definition AudioStreamCallback.h:210
Definition ResultWithValue.h:47
Definition AudioStream.h:36
Definition Definitions.h:1135
Definition AudioStream.h:979