Oboe 1.5 A library for creating real-time audio apps on Android

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
31 namespace oboe {
32
39 constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond);
40
44 class AudioStream : public AudioStreamBase {
45 friend class AudioStreamBuilder; // allow access to setWeakThis() and lockWeakThis()
46 public:
47
48 AudioStream() {}
49
55 explicit AudioStream(const AudioStreamBuilder &builder);
56
57 virtual ~AudioStream() = default;
58
67 virtual Result open() {
68 return Result::OK; // Called by subclasses. Might do more in the future.
69 }
70
74 virtual Result close();
75
80 virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
81
86 virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
87
92 virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
93
98 virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
99
100 /* Asynchronous requests.
101 * Use waitForStateChange() if you need to wait for completion.
102 */
103
108 virtual Result requestStart() = 0;
109
114 virtual Result requestPause() = 0;
115
120 virtual Result requestFlush() = 0;
121
126 virtual Result requestStop() = 0;
127
133 virtual StreamState getState() const = 0;
134
162 virtual Result waitForStateChange(StreamState inputState,
163 StreamState *nextState,
164 int64_t timeoutNanoseconds) = 0;
165
178 virtual ResultWithValue<int32_t> setBufferSizeInFrames(int32_t /* requestedFrames */) {
179 return Result::ErrorUnimplemented;
180 }
181
194 virtual ResultWithValue<int32_t> getXRunCount() const {
195 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
196 }
197
201 virtual bool isXRunCountSupported() const = 0;
202
208 virtual int32_t getFramesPerBurst() = 0;
209
217 int32_t getBytesPerFrame() const { return mChannelCount * getBytesPerSample(); }
218
225 int32_t getBytesPerSample() const;
226
233 virtual int64_t getFramesWritten();
234
241 virtual int64_t getFramesRead();
242
266 virtual ResultWithValue<double> calculateLatencyMillis() {
267 return ResultWithValue<double>(Result::ErrorUnimplemented);
268 }
269
287 virtual Result getTimestamp(clockid_t /* clockId */,
288 int64_t* /* framePosition */,
289 int64_t* /* timeNanoseconds */) {
290 return Result::ErrorUnimplemented;
291 }
292
308 virtual ResultWithValue<FrameTimestamp> getTimestamp(clockid_t /* clockId */);
309
310 // ============== I/O ===========================
323 virtual ResultWithValue<int32_t> write(const void* /* buffer */,
324 int32_t /* numFrames */,
325 int64_t /* timeoutNanoseconds */ ) {
326 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
327 }
328
341 virtual ResultWithValue<int32_t> read(void* /* buffer */,
342 int32_t /* numFrames */,
343 int64_t /* timeoutNanoseconds */) {
344 return ResultWithValue<int32_t>(Result::ErrorUnimplemented);
345 }
346
352 virtual AudioApi getAudioApi() const = 0;
353
359 bool usesAAudio() const {
360 return getAudioApi() == AudioApi::AAudio;
361 }
362
371 virtual void *getUnderlyingStream() const {
372 return nullptr;
373 }
374
378 void launchStopThread();
379
384 virtual void updateFramesWritten() = 0;
385
390 virtual void updateFramesRead() = 0;
391
392 /*
393 * Swap old callback for new callback.
394 * This not atomic.
395 * This should only be used internally.
396 * @param dataCallback
397 * @return previous dataCallback
398 */
399 AudioStreamDataCallback *swapDataCallback(AudioStreamDataCallback *dataCallback) {
400 AudioStreamDataCallback *previousCallback = mDataCallback;
401 mDataCallback = dataCallback;
402 return previousCallback;
403 }
404
405 /*
406 * Swap old callback for new callback.
407 * This not atomic.
408 * This should only be used internally.
409 * @param errorCallback
410 * @return previous errorCallback
411 */
412 AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) {
413 AudioStreamErrorCallback *previousCallback = mErrorCallback;
414 mErrorCallback = errorCallback;
415 return previousCallback;
416 }
417
421 ResultWithValue<int32_t> getAvailableFrames();
422
432 ResultWithValue<int32_t> waitForAvailableFrames(int32_t numFrames,
433 int64_t timeoutNanoseconds);
434
438 virtual oboe::Result getLastErrorCallbackResult() const {
439 return mErrorCallbackResult;
440 }
441
442 protected:
443
453 bool wasErrorCallbackCalled() {
454 return mErrorCallbackCalled.exchange(true);
455 }
456
463 virtual Result waitForStateTransition(StreamState startingState,
464 StreamState endingState,
465 int64_t timeoutNanoseconds);
466
474 virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) {
475 return DataCallbackResult::Stop;
476 }
477
486 DataCallbackResult fireDataCallback(void *audioData, int numFrames);
487
491 bool isDataCallbackEnabled() {
492 return mDataCallbackEnabled;
493 }
494
499 void setDataCallbackEnabled(bool enabled) {
500 mDataCallbackEnabled = enabled;
501 }
502
503 /*
504 * Set a weak_ptr to this stream from the shared_ptr so that we can
505 * later use a shared_ptr in the error callback.
506 */
507 void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) {
508 mWeakThis = sharedStream;
509 }
510
511 /*
512 * Make a shared_ptr that will prevent this stream from being deleted.
513 */
514 std::shared_ptr<oboe::AudioStream> lockWeakThis() {
515 return mWeakThis.lock();
516 }
517
518 std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object
519
526 std::atomic<int64_t> mFramesWritten{};
527
534 std::atomic<int64_t> mFramesRead{};
535
536 std::mutex mLock; // for synchronizing start/stop/close
537
538 oboe::Result mErrorCallbackResult = oboe::Result::OK;
539
540 private:
541
542 // Log the scheduler if it changes.
543 void checkScheduler();
544 int mPreviousScheduler = -1;
545
546 std::atomic<bool> mDataCallbackEnabled{false};
547 std::atomic<bool> mErrorCallbackCalled{false};
548
549 };
550
555 struct StreamDeleterFunctor {
556 void operator()(AudioStream *audioStream) {
557 if (audioStream) {
558 audioStream->close();
559 }
560 delete audioStream;
561 }
562 };
563 } // namespace oboe
564
565 #endif /* OBOE_STREAM_H_ */
oboe::AudioStream::onDefaultCallback
virtual DataCallbackResult onDefaultCallback(void *, int)
Definition: AudioStream.h:474
oboe::AudioStream::stop
virtual Result stop(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
oboe::AudioApi::AAudio
oboe::AudioStreamBuilder
Definition: AudioStreamBuilder.h:33
oboe::AudioStream::getAvailableFrames
ResultWithValue< int32_t > getAvailableFrames()
oboe::AudioStream::setDataCallbackEnabled
void setDataCallbackEnabled(bool enabled)
Definition: AudioStream.h:499
oboe::AudioStream::usesAAudio
bool usesAAudio() const
Definition: AudioStream.h:359
oboe::AudioStream::flush
virtual Result flush(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
oboe::AudioStreamBase::mDataCallback
AudioStreamDataCallback * mDataCallback
Definition: AudioStreamBase.h:182
oboe::AudioStream::getBytesPerFrame
int32_t getBytesPerFrame() const
Definition: AudioStream.h:217
oboe::AudioStream::start
virtual Result start(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
oboe::kDefaultTimeoutNanos
constexpr int64_t kDefaultTimeoutNanos
Definition: AudioStream.h:39
oboe::AudioStream::getXRunCount
virtual ResultWithValue< int32_t > getXRunCount() const
Definition: AudioStream.h:194
oboe::AudioStream::mFramesWritten
std::atomic< int64_t > mFramesWritten
Definition: AudioStream.h:526
oboe::AudioStream::fireDataCallback
DataCallbackResult fireDataCallback(void *audioData, int numFrames)
oboe::AudioStream::getUnderlyingStream
virtual void * getUnderlyingStream() const
Definition: AudioStream.h:371
oboe::AudioStream::updateFramesWritten
virtual void updateFramesWritten()=0
oboe::AudioStream::getFramesWritten
virtual int64_t getFramesWritten()
oboe::AudioStream::waitForAvailableFrames
ResultWithValue< int32_t > waitForAvailableFrames(int32_t numFrames, int64_t timeoutNanoseconds)
oboe::AudioStreamDataCallback
Definition: AudioStreamCallback.h:34
oboe::AudioStreamBase::mChannelCount
int32_t mChannelCount
Definition: AudioStreamBase.h:190
oboe::DataCallbackResult
DataCallbackResult
Definition: Definitions.h:119
oboe::AudioApi
AudioApi
Definition: Definitions.h:213
oboe::AudioStream::waitForStateTransition
virtual Result waitForStateTransition(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)
oboe::AudioStream::getFramesPerBurst
virtual int32_t getFramesPerBurst()=0
oboe::AudioStream::close
virtual Result close()
oboe::AudioStream::setBufferSizeInFrames
virtual ResultWithValue< int32_t > setBufferSizeInFrames(int32_t)
Definition: AudioStream.h:178
oboe::AudioStream::calculateLatencyMillis
virtual ResultWithValue< double > calculateLatencyMillis()
Definition: AudioStream.h:266
oboe::AudioStream::getTimestamp
virtual Result getTimestamp(clockid_t, int64_t *, int64_t *)
Definition: AudioStream.h:287
oboe::AudioStream::open
virtual Result open()
Definition: AudioStream.h:67
oboe::AudioStream::getFramesRead
virtual int64_t getFramesRead()
oboe::AudioStream
Definition: AudioStream.h:44
oboe::AudioStream::isDataCallbackEnabled
bool isDataCallbackEnabled()
Definition: AudioStream.h:491
oboe::AudioStream::read
virtual ResultWithValue< int32_t > read(void *, int32_t, int64_t)
Definition: AudioStream.h:341
oboe::AudioStream::requestPause
virtual Result requestPause()=0
oboe::AudioStream::write
virtual ResultWithValue< int32_t > write(const void *, int32_t, int64_t)
Definition: AudioStream.h:323
oboe::AudioStream::mFramesRead
std::atomic< int64_t > mFramesRead
Definition: AudioStream.h:534
oboe::AudioStreamBase
Definition: AudioStreamBase.h:29
oboe::kNanosPerMillisecond
constexpr int64_t kNanosPerMillisecond
Definition: Definitions.h:43
oboe::AudioStream::requestStop
virtual Result requestStop()=0
oboe::AudioStream::getAudioApi
virtual AudioApi getAudioApi() const =0
oboe::AudioStream::launchStopThread
void launchStopThread()
oboe::AudioStream::waitForStateChange
virtual Result waitForStateChange(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0
oboe::Result
Result
Definition: Definitions.h:131
oboe::StreamDeleterFunctor
Definition: AudioStream.h:555
oboe
Definition: AudioStream.h:31
oboe::AudioStream::wasErrorCallbackCalled
bool wasErrorCallbackCalled()
Definition: AudioStream.h:453
oboe::AudioStream::isXRunCountSupported
virtual bool isXRunCountSupported() const =0
oboe::AudioStream::requestStart
virtual Result requestStart()=0
oboe::AudioStream::getLastErrorCallbackResult
virtual oboe::Result getLastErrorCallbackResult() const
Definition: AudioStream.h:438
oboe::StreamState
StreamState
Definition: Definitions.h:58
oboe::AudioStream::getState
virtual StreamState getState() const =0
oboe::AudioStream::pause
virtual Result pause(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
oboe::AudioStream::requestFlush
virtual Result requestFlush()=0
oboe::AudioStream::updateFramesRead
virtual void updateFramesRead()=0
oboe::AudioStreamBase::mErrorCallback
AudioStreamErrorCallback * mErrorCallback
Definition: AudioStreamBase.h:185
oboe::AudioStream::getBytesPerSample
int32_t getBytesPerSample() const
oboe::ResultWithValue
Definition: ResultWithValue.h:47