Oboe
A library for creating real-time audio apps on Android
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | Friends | List of all members
oboe::AudioStream Class Referenceabstract

#include <AudioStream.h>

Inheritance diagram for oboe::AudioStream:
oboe::AudioStreamBase

Public Member Functions

 AudioStream (const AudioStreamBuilder &builder)
 
virtual Result open ()
 
virtual Result close ()
 
virtual Result start (int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
 
virtual Result pause (int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
 
virtual Result flush (int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
 
virtual Result stop (int64_t timeoutNanoseconds=kDefaultTimeoutNanos)
 
virtual Result requestStart ()=0
 
virtual Result requestPause ()=0
 
virtual Result requestFlush ()=0
 
virtual Result requestStop ()=0
 
virtual StreamState getState ()=0
 
virtual Result waitForStateChange (StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0
 
virtual ResultWithValue< int32_t > setBufferSizeInFrames (int32_t)
 
virtual ResultWithValue< int32_t > getXRunCount ()
 
virtual bool isXRunCountSupported () const =0
 
int32_t getFramesPerBurst () const
 
int32_t getBytesPerFrame () const
 
int32_t getBytesPerSample () const
 
virtual int64_t getFramesWritten ()
 
virtual int64_t getFramesRead ()
 
virtual ResultWithValue< double > calculateLatencyMillis ()
 
virtual Result getTimestamp (clockid_t, int64_t *, int64_t *)
 
virtual ResultWithValue< FrameTimestampgetTimestamp (clockid_t)
 
virtual ResultWithValue< int32_t > write (const void *, int32_t, int64_t)
 
virtual ResultWithValue< int32_t > read (void *, int32_t, int64_t)
 
virtual AudioApi getAudioApi () const =0
 
bool usesAAudio () const
 
virtual void * getUnderlyingStream () const
 
virtual void updateFramesWritten ()=0
 
virtual void updateFramesRead ()=0
 
AudioStreamDataCallbackswapDataCallback (AudioStreamDataCallback *dataCallback)
 
AudioStreamErrorCallbackswapErrorCallback (AudioStreamErrorCallback *errorCallback)
 
ResultWithValue< int32_t > getAvailableFrames ()
 
ResultWithValue< int32_t > waitForAvailableFrames (int32_t numFrames, int64_t timeoutNanoseconds)
 
virtual oboe::Result getLastErrorCallbackResult () const
 
int32_t getDelayBeforeCloseMillis () const
 
void setDelayBeforeCloseMillis (int32_t delayBeforeCloseMillis)
 
- Public Member Functions inherited from oboe::AudioStreamBase
 AudioStreamBase (const AudioStreamBase &)=default
 
AudioStreamBaseoperator= (const AudioStreamBase &)=default
 
int32_t getChannelCount () const
 
Direction getDirection () const
 
int32_t getSampleRate () const
 
int32_t getFramesPerCallback () const
 
int32_t getFramesPerDataCallback () const
 
AudioFormat getFormat () const
 
virtual int32_t getBufferSizeInFrames ()
 
virtual int32_t getBufferCapacityInFrames () const
 
SharingMode getSharingMode () const
 
PerformanceMode getPerformanceMode () const
 
int32_t getDeviceId () const
 
AudioStreamDataCallbackgetDataCallback () const
 
AudioStreamErrorCallbackgetErrorCallback () const
 
bool isDataCallbackSpecified () const
 
bool isErrorCallbackSpecified () const
 
Usage getUsage () const
 
ContentType getContentType () const
 
InputPreset getInputPreset () const
 
SessionId getSessionId () const
 
bool isChannelConversionAllowed () const
 
bool isFormatConversionAllowed () const
 
SampleRateConversionQuality getSampleRateConversionQuality () const
 
ChannelMask getChannelMask () const
 

Protected Member Functions

bool wasErrorCallbackCalled ()
 
virtual Result waitForStateTransition (StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)
 
virtual DataCallbackResult onDefaultCallback (void *, int)
 
DataCallbackResult fireDataCallback (void *audioData, int numFrames)
 
bool isDataCallbackEnabled ()
 
void setDataCallbackEnabled (bool enabled)
 
void calculateDefaultDelayBeforeCloseMillis ()
 
void sleepBeforeClose ()
 
void setWeakThis (std::shared_ptr< oboe::AudioStream > &sharedStream)
 
std::shared_ptr< oboe::AudioStreamlockWeakThis ()
 
- Protected Member Functions inherited from oboe::AudioStreamBase
virtual Result isValidConfig ()
 

Protected Attributes

std::weak_ptr< AudioStreammWeakThis
 
std::atomic< int64_t > mFramesWritten {}
 
std::atomic< int64_t > mFramesRead {}
 
std::mutex mLock
 
oboe::Result mErrorCallbackResult = oboe::Result::OK
 
int32_t mFramesPerBurst = kUnspecified
 
int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis
 
- Protected Attributes inherited from oboe::AudioStreamBase
AudioStreamDataCallbackmDataCallback = nullptr
 
std::shared_ptr< AudioStreamDataCallbackmSharedDataCallback
 
AudioStreamErrorCallbackmErrorCallback = nullptr
 
std::shared_ptr< AudioStreamErrorCallbackmSharedErrorCallback
 
int32_t mFramesPerCallback = kUnspecified
 
int32_t mChannelCount = kUnspecified
 
int32_t mSampleRate = kUnspecified
 
int32_t mDeviceId = kUnspecified
 
int32_t mBufferCapacityInFrames = kUnspecified
 
int32_t mBufferSizeInFrames = kUnspecified
 
ChannelMask mChannelMask = ChannelMask::Unspecified
 
SharingMode mSharingMode = SharingMode::Shared
 
AudioFormat mFormat = AudioFormat::Unspecified
 
Direction mDirection = Direction::Output
 
PerformanceMode mPerformanceMode = PerformanceMode::None
 
Usage mUsage = Usage::Media
 
ContentType mContentType = ContentType::Music
 
InputPreset mInputPreset = InputPreset::VoiceRecognition
 
SessionId mSessionId = SessionId::None
 
std::string mPackageName
 
std::string mAttributionTag
 
bool mChannelConversionAllowed = false
 
bool mFormatConversionAllowed = false
 
SampleRateConversionQuality mSampleRateConversionQuality = SampleRateConversionQuality::None
 

Static Protected Attributes

static constexpr int kMinDelayBeforeCloseMillis = 10
 

Friends

class AudioStreamBuilder
 

Detailed Description

Base class for Oboe C++ audio stream.

Constructor & Destructor Documentation

◆ AudioStream()

oboe::AudioStream::AudioStream ( const AudioStreamBuilder builder)
explicit

Construct an AudioStream using the given AudioStreamBuilder

Parameters
buildercontaining all the stream's attributes

Member Function Documentation

◆ calculateDefaultDelayBeforeCloseMillis()

void oboe::AudioStream::calculateDefaultDelayBeforeCloseMillis ( )
protected

This should only be called as a stream is being opened. Otherwise we might override setDelayBeforeCloseMillis().

◆ calculateLatencyMillis()

virtual ResultWithValue< double > oboe::AudioStream::calculateLatencyMillis ( )
inlinevirtual

Calculate the latency of a stream based on getTimestamp().

Output latency is the time it takes for a given frame to travel from the app to some type of digital-to-analog converter. If the DAC is external, for example in a USB interface or a TV connected by HDMI, then there may be additional latency that the Android device is unaware of.

Input latency is the time it takes to a given frame to travel from an analog-to-digital converter (ADC) to the app.

Note that the latency of an OUTPUT stream will increase abruptly when you write data to it and then decrease slowly over time as the data is consumed.

The latency of an INPUT stream will decrease abruptly when you read data from it and then increase slowly over time as more data arrives.

The latency of an OUTPUT stream is generally higher than the INPUT latency because an app generally tries to keep the OUTPUT buffer full and the INPUT buffer empty.

Note that due to issues in Android before R, we recommend NOT calling this method from a data callback. See this tech note for more details. https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md

Returns
a ResultWithValue which has a result of Result::OK and a value containing the latency in milliseconds, or a result of Result::Error*.

◆ close()

virtual Result oboe::AudioStream::close ( )
virtual

Close the stream and deallocate any resources from the open() call.

◆ fireDataCallback()

DataCallbackResult oboe::AudioStream::fireDataCallback ( void *  audioData,
int  numFrames 
)
protected

Override this to provide your own behaviour for the audio callback

Parameters
audioDatacontainer array which audio frames will be written into or read from
numFramesnumber of frames which were read/written
Returns
the result of the callback: stop or continue

◆ flush()

virtual Result oboe::AudioStream::flush ( int64_t  timeoutNanoseconds = kDefaultTimeoutNanos)
virtual

Flush the stream. This will block until the stream has been flushed, an error occurs or timeoutNanoseconds has been reached.

◆ getAudioApi()

virtual AudioApi oboe::AudioStream::getAudioApi ( ) const
pure virtual

Get the underlying audio API which the stream uses.

Returns
the API that this stream uses.

◆ getAvailableFrames()

ResultWithValue< int32_t > oboe::AudioStream::getAvailableFrames ( )
Returns
number of frames of data currently in the buffer

◆ getBytesPerFrame()

int32_t oboe::AudioStream::getBytesPerFrame ( ) const
inline

Get the number of bytes in each audio frame. This is calculated using the channel count and the sample format. For example, a 2 channel floating point stream will have 2 * 4 = 8 bytes per frame.

Returns
number of bytes in each audio frame.

◆ getBytesPerSample()

int32_t oboe::AudioStream::getBytesPerSample ( ) const

Get the number of bytes per sample. This is calculated using the sample format. For example, a stream using 16-bit integer samples will have 2 bytes per sample.

Returns
the number of bytes per sample.

◆ getFramesPerBurst()

int32_t oboe::AudioStream::getFramesPerBurst ( ) const
inline

Query the number of frames that are read or written by the endpoint at one time.

Returns
burst size

◆ getFramesRead()

virtual int64_t oboe::AudioStream::getFramesRead ( )
virtual

The number of audio frames read from the stream. This monotonic counter will never get reset.

Returns
the number of frames read so far

◆ getFramesWritten()

virtual int64_t oboe::AudioStream::getFramesWritten ( )
virtual

The number of audio frames written into the stream. This monotonic counter will never get reset.

Returns
the number of frames written so far

◆ getLastErrorCallbackResult()

virtual oboe::Result oboe::AudioStream::getLastErrorCallbackResult ( ) const
inlinevirtual
Returns
last result passed from an error callback

◆ getState()

virtual StreamState oboe::AudioStream::getState ( )
pure virtual

Query the current state, eg. StreamState::Pausing

Returns
state or a negative error.

◆ getTimestamp() [1/2]

virtual ResultWithValue< FrameTimestamp > oboe::AudioStream::getTimestamp ( clockid_t  )
virtual

Get the estimated time that the frame at framePosition entered or left the audio processing pipeline.

This can be used to coordinate events and interactions with the external environment, and to estimate the latency of an audio stream. An example of usage can be found in the hello-oboe sample (search for "calculateCurrentOutputLatencyMillis").

The time is based on the implementation's best effort, using whatever knowledge is available to the system, but cannot account for any delay unknown to the implementation.

Note that due to issues in Android before R, we recommend NOT calling this method from a data callback. See this tech note for more details. https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md

See

Parameters
clockIdthe type of clock to use e.g. CLOCK_MONOTONIC
Returns
a FrameTimestamp containing the position and time at which a particular audio frame entered or left the audio processing pipeline, or an error if the operation failed.

◆ getTimestamp() [2/2]

virtual Result oboe::AudioStream::getTimestamp ( clockid_t  ,
int64_t *  ,
int64_t *   
)
inlinevirtual

Get the estimated time that the frame at framePosition entered or left the audio processing pipeline.

This can be used to coordinate events and interactions with the external environment, and to estimate the latency of an audio stream. An example of usage can be found in the hello-oboe sample (search for "calculateCurrentOutputLatencyMillis").

The time is based on the implementation's best effort, using whatever knowledge is available to the system, but cannot account for any delay unknown to the implementation.

Note that due to issues in Android before R, we recommend NOT calling this method from a data callback. See this tech note for more details. https://github.com/google/oboe/blob/main/docs/notes/rlsbuffer.md

Deprecated:
since 1.0, use AudioStream::getTimestamp(clockid_t clockId) instead, which returns ResultWithValue
Parameters
clockIdthe type of clock to use e.g. CLOCK_MONOTONIC
framePositionthe frame number to query
timeNanosecondsan output parameter which will contain the presentation timestamp

◆ getUnderlyingStream()

virtual void * oboe::AudioStream::getUnderlyingStream ( ) const
inlinevirtual

Only for debugging. Do not use in production. If you need to call this method something is wrong. If you think you need it for production then please let us know so we can modify Oboe so that you don't need this.

Returns
nullptr or a pointer to a stream from the system API

◆ getXRunCount()

virtual ResultWithValue< int32_t > oboe::AudioStream::getXRunCount ( )
inlinevirtual

An XRun is an Underrun or an Overrun. During playing, an underrun will occur if the stream is not written in time and the system runs out of valid data. During recording, an overrun will occur if the stream is not read in time and there is no place to put the incoming data so it is discarded.

An underrun or overrun can cause an audible "pop" or "glitch".

Returns
a result which is either Result::OK with the xRun count as the value, or a Result::Error* code

◆ isDataCallbackEnabled()

bool oboe::AudioStream::isDataCallbackEnabled ( )
inlineprotected
Returns
true if callbacks may be called

◆ isXRunCountSupported()

virtual bool oboe::AudioStream::isXRunCountSupported ( ) const
pure virtual
Returns
true if XRun counts are supported on the stream

◆ onDefaultCallback()

virtual DataCallbackResult oboe::AudioStream::onDefaultCallback ( void *  ,
int   
)
inlineprotectedvirtual

Override this to provide a default for when the application did not specify a callback.

Parameters
audioData
numFrames
Returns
result

◆ open()

virtual Result oboe::AudioStream::open ( )
inlinevirtual

Open a stream based on the current settings.

Note that we do not recommend re-opening a stream that has been closed. TODO Should we prevent re-opening?

Returns

◆ pause()

virtual Result oboe::AudioStream::pause ( int64_t  timeoutNanoseconds = kDefaultTimeoutNanos)
virtual

Pause the stream. This will block until the stream has been paused, an error occurs or timeoutNanoseconds has been reached.

◆ read()

virtual ResultWithValue< int32_t > oboe::AudioStream::read ( void *  ,
int32_t  ,
int64_t   
)
inlinevirtual

Read data into the supplied buffer from the stream. This method will block until the read is complete or it runs out of time.

If timeoutNanoseconds is zero then this call will not wait.

Parameters
bufferThe address of the first sample.
numFramesNumber of frames to read. Only complete frames will be read.
timeoutNanosecondsMaximum number of nanoseconds to wait for completion.
Returns
a ResultWithValue which has a result of Result::OK and a value containing the number of frames actually read, or result of Result::Error*.

◆ requestFlush()

virtual Result oboe::AudioStream::requestFlush ( )
pure virtual

Flush the stream asynchronously. Returns immediately (does not block). Equivalent to calling flush(0).

◆ requestPause()

virtual Result oboe::AudioStream::requestPause ( )
pure virtual

Pause the stream asynchronously. Returns immediately (does not block). Equivalent to calling pause(0).

◆ requestStart()

virtual Result oboe::AudioStream::requestStart ( )
pure virtual

Start the stream asynchronously. Returns immediately (does not block). Equivalent to calling start(0).

◆ requestStop()

virtual Result oboe::AudioStream::requestStop ( )
pure virtual

Stop the stream asynchronously. Returns immediately (does not block). Equivalent to calling stop(0).

◆ setBufferSizeInFrames()

virtual ResultWithValue< int32_t > oboe::AudioStream::setBufferSizeInFrames ( int32_t  )
inlinevirtual

This can be used to adjust the latency of the buffer by changing the threshold where blocking will occur. By combining this with getXRunCount(), the latency can be tuned at run-time for each device.

This cannot be set higher than getBufferCapacity().

Parameters
requestedFramesrequested number of frames that can be filled without blocking
Returns
the resulting buffer size in frames (obtained using value()) or an error (obtained using error())

◆ setDataCallbackEnabled()

void oboe::AudioStream::setDataCallbackEnabled ( bool  enabled)
inlineprotected

This can be set false internally to prevent callbacks after DataCallbackResult::Stop has been returned.

◆ setDelayBeforeCloseMillis()

void oboe::AudioStream::setDelayBeforeCloseMillis ( int32_t  delayBeforeCloseMillis)
inline

Set the time to sleep before closing the internal stream.

Sometimes a callback can occur shortly after a stream has been stopped and even after a close! If the stream has been closed then the callback might access memory that has been freed, which could cause a crash. This seems to be more likely in Android P or earlier. But it can also occur in later versions. By sleeping, we give time for the callback threads to finish.

Note that this only has an effect when OboeGlobals::areWorkaroundsEnabled() is true.

Parameters
delayBeforeCloseMillistime to sleep before close.

◆ sleepBeforeClose()

void oboe::AudioStream::sleepBeforeClose ( )
inlineprotected

Try to avoid a race condition when closing.

◆ start()

virtual Result oboe::AudioStream::start ( int64_t  timeoutNanoseconds = kDefaultTimeoutNanos)
virtual

Start the stream. This will block until the stream has been started, an error occurs or timeoutNanoseconds has been reached.

◆ stop()

virtual Result oboe::AudioStream::stop ( int64_t  timeoutNanoseconds = kDefaultTimeoutNanos)
virtual

Stop the stream. This will block until the stream has been stopped, an error occurs or timeoutNanoseconds has been reached.

◆ updateFramesRead()

virtual void oboe::AudioStream::updateFramesRead ( )
pure virtual

Update mFramesRead. For internal use only.

◆ updateFramesWritten()

virtual void oboe::AudioStream::updateFramesWritten ( )
pure virtual

Update mFramesWritten. For internal use only.

◆ usesAAudio()

bool oboe::AudioStream::usesAAudio ( ) const
inline

Returns true if the underlying audio API is AAudio.

Returns
true if this stream is implemented using the AAudio API.

◆ waitForAvailableFrames()

ResultWithValue< int32_t > oboe::AudioStream::waitForAvailableFrames ( int32_t  numFrames,
int64_t  timeoutNanoseconds 
)

Wait until the stream has a minimum amount of data available in its buffer. This can be used with an EXCLUSIVE MMAP input stream to avoid reading data too close to the DSP write position, which may cause glitches.

Parameters
numFramesminimum frames available
timeoutNanoseconds
Returns
number of frames available, ErrorTimeout

◆ waitForStateChange()

virtual Result oboe::AudioStream::waitForStateChange ( StreamState  inputState,
StreamState nextState,
int64_t  timeoutNanoseconds 
)
pure virtual

Wait until the stream's current state no longer matches the input state. The input state is passed to avoid race conditions caused by the state changing between calls.

Note that generally applications do not need to call this. It is considered an advanced technique and is mostly used for testing.


int64_t timeoutNanos = 500 * kNanosPerMillisecond; // arbitrary 1/2 second
StreamState currentState = stream->getState();
StreamState nextState = StreamState::Unknown;
while (result == Result::OK && currentState != StreamState::Paused) {
    result = stream->waitForStateChange(
                                  currentState, &nextState, timeoutNanos);
    currentState = nextState;
}

If the state does not change within the timeout period then it will return ErrorTimeout. This is true even if timeoutNanoseconds is zero.

Parameters
inputStateThe state we want to change away from.
nextStatePointer to a variable that will be set to the new state.
timeoutNanosecondsThe maximum time to wait in nanoseconds.
Returns
Result::OK or a Result::Error.

◆ waitForStateTransition()

virtual Result oboe::AudioStream::waitForStateTransition ( StreamState  startingState,
StreamState  endingState,
int64_t  timeoutNanoseconds 
)
protectedvirtual

Wait for a transition from one state to another.

Returns
OK if the endingState was observed, or ErrorUnexpectedState if any state that was not the startingState or endingState was observed or ErrorTimeout.

◆ wasErrorCallbackCalled()

bool oboe::AudioStream::wasErrorCallbackCalled ( )
inlineprotected

This is used to detect more than one error callback from a stream. These were bugs in some versions of Android that caused multiple error callbacks. Internal bug b/63087953

Calling this sets an atomic<bool> true and returns the previous value.

Returns
false on first call, true on subsequent calls

◆ write()

virtual ResultWithValue< int32_t > oboe::AudioStream::write ( const void *  ,
int32_t  ,
int64_t   
)
inlinevirtual

Write data from the supplied buffer into the stream. This method will block until the write is complete or it runs out of time.

If timeoutNanoseconds is zero then this call will not wait.

Parameters
bufferThe address of the first sample.
numFramesNumber of frames to write. Only complete frames will be written.
timeoutNanosecondsMaximum number of nanoseconds to wait for completion.
Returns
a ResultWithValue which has a result of Result::OK and a value containing the number of frames actually written, or result of Result::Error*.

Member Data Documentation

◆ mFramesPerBurst

int32_t oboe::AudioStream::mFramesPerBurst = kUnspecified
protected

Number of frames which will be copied to/from the audio device in a single read/write operation

◆ mFramesRead

std::atomic<int64_t> oboe::AudioStream::mFramesRead {}
protected

Number of frames which have been read from the stream.

This is signed integer to match the counters in AAudio. At audio rates, the counter will overflow in about six million years.

◆ mFramesWritten

std::atomic<int64_t> oboe::AudioStream::mFramesWritten {}
protected

Number of frames which have been written into the stream

This is signed integer to match the counters in AAudio. At audio rates, the counter will overflow in about six million years.


The documentation for this class was generated from the following file: