|
| AudioStream (const AudioStreamBuilder &builder) |
|
virtual Result | open () |
|
virtual Result | release () |
|
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< FrameTimestamp > | getTimestamp (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 |
|
AudioStreamDataCallback * | swapDataCallback (AudioStreamDataCallback *dataCallback) |
|
AudioStreamErrorCallback * | swapErrorCallback (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) |
|
void | setPerformanceHintEnabled (bool enabled) |
|
bool | isPerformanceHintEnabled () |
|
virtual oboe::Result | reportWorkload (int32_t appWorkload) |
|
virtual oboe::Result | notifyWorkloadIncrease (bool cpu, bool gpu, const char *debugName) |
|
virtual oboe::Result | notifyWorkloadReset (bool cpu, bool gpu, const char *debugName) |
|
virtual oboe::Result | notifyWorkloadSpike (bool cpu, bool gpu, const char *debugName) |
|
virtual oboe::Result | setOffloadDelayPadding (int32_t delayInFrames, int32_t paddingInFrames) |
|
virtual ResultWithValue< int32_t > | getOffloadDelay () |
|
virtual ResultWithValue< int32_t > | getOffloadPadding () |
|
virtual oboe::Result | setOffloadEndOfStream () |
|
virtual ResultWithValue< int64_t > | flushFromFrame (FlushFromAccuracy accuracy, int64_t positionInFrames) |
|
virtual oboe::Result | setPlaybackParameters (const PlaybackParameters ¶meters) |
|
virtual ResultWithValue< PlaybackParameters > | getPlaybackParameters () |
|
| AudioStreamBase (const AudioStreamBase &)=default |
|
AudioStreamBase & | operator= (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 |
|
std::vector< int32_t > | getDeviceIds () const |
|
AudioStreamDataCallback * | getDataCallback () const |
|
AudioStreamErrorCallback * | getErrorCallback () const |
|
std::shared_ptr< AudioStreamPresentationCallback > | getPresentationCallback () const |
|
bool | isDataCallbackSpecified () const |
|
bool | isErrorCallbackSpecified () const |
|
bool | isPresentationCallbackSpecified () const |
|
Usage | getUsage () const |
|
ContentType | getContentType () const |
|
InputPreset | getInputPreset () const |
|
SessionId | getSessionId () const |
|
bool | isContentSpatialized () const |
|
SpatializationBehavior | getSpatializationBehavior () const |
|
AllowedCapturePolicy | getAllowedCapturePolicy () const |
|
PrivacySensitiveMode | getPrivacySensitiveMode () const |
|
std::string | getPackageName () const |
|
std::string | getAttributionTag () const |
|
bool | isChannelConversionAllowed () const |
|
bool | isFormatConversionAllowed () const |
|
SampleRateConversionQuality | getSampleRateConversionQuality () const |
|
ChannelMask | getChannelMask () const |
|
int32_t | getHardwareChannelCount () const |
|
int32_t | getHardwareSampleRate () const |
|
AudioFormat | getHardwareFormat () const |
|
Base class for Oboe C++ audio stream.
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/wiki/TechNote_ReleaseBuffer
- Returns
- a ResultWithValue which has a result of Result::OK and a value containing the latency in milliseconds, or a result of Result::Error*.
virtual ResultWithValue< int64_t > oboe::AudioStream::flushFromFrame |
( |
FlushFromAccuracy | accuracy, |
|
|
int64_t | positionInFrames ) |
|
inlinevirtual |
Flush all data from given position. If this operation returns successfully, the following data will be written from the returned position.
This method will only available when the performance mode is PerformanceMode::PowerSavingOffloaded.
The requested position must not be negative or greater than the written frames. The current written position can be known by querying getFramesWritten().
When clients request to flush from a certain position, the audio system will return the actual flushed position based on the requested position, playback latency, etc. The written position will be updated as the actual flush position. All data after actual flush position flushed. The client can provide data from actual flush position at next write operation or data callback request. When the stream is flushed, the stream end will be reset. The client must not write any data before this function returns. Otherwise, the data will be corrupted. When the method returns successfully and the stream is active, the client must write data immediately if little audio data remains. Otherwise, the stream will underrun.
This was introduced in Android API Level 37.
- Parameters
-
accuracy | the accuracy requirement when flushing. The value must be one of the valid FlushFromAccuracy value. |
position | the start point in frames to flush the stream. |
- Returns
- a result which the error code indicates if the stream is successfully flush or not and value as the successfully flushed position or suggested flushed position. Result::OK if the stream is successfully flushed. The value is the actual flushed position. Result::ErrorUnimplemented if it is not supported by the device. The value is the requested position. Result::ErrorIllegalArgument if the stream is not an output offload stream or the accuracy is not one of valid FlushFromAccuracy values. The value is the requested position. Result::ErrorOutOfRange if the provided position is negative or is greater than the frames written or the stream cannot flush from the requested position and FlushFromAccuracy::Accurate is requested. The value is suggested flushed position. Result::ErrorDisconnected if the stream is disconnected. The value is the requested position. Result::ErrorClosed if the stream is closed. The value is the requested position.
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/wiki/TechNote_ReleaseBuffer
See
- Parameters
-
clockId | the 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.
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/wiki/TechNote_ReleaseBuffer
- Deprecated
- since 1.0, use AudioStream::getTimestamp(clockid_t clockId) instead, which returns ResultWithValue
- Parameters
-
clockId | the type of clock to use e.g. CLOCK_MONOTONIC |
framePosition | the frame number to query |
timeNanoseconds | an output parameter which will contain the presentation timestamp |
virtual oboe::Result oboe::AudioStream::notifyWorkloadReset |
( |
bool | cpu, |
|
|
bool | gpu, |
|
|
const char * | debugName ) |
|
inlinevirtual |
Informs the framework of an upcoming reset in the workload of an audio callback bound to this session, or the imminent start of a new workload. The user can specify whether the reset is expected to affect the CPU, GPU, or both.
Sending hints for both CPU and GPU counts as two separate hints for the purposes of the this load tracking.
- Parameters
-
cpu | Indicates if the workload reset is expected to affect the CPU. |
gpu | Indicates if the workload reset is expected to affect the GPU. |
debugName | A required string used to identify this specific hint during tracing. This debug string will only be held for the duration of the method, and can be safely discarded after. |
This was introduced in Android API Level 36
- Returns
- Result::OK on success. Result::ErrorInvalidState if the PerformanceHint was not enabled. Result::ErrorClosed if AdpfWrapper::open() was not called. Result::ErrorUnimplemented if the API is not supported. Result::ErrorInvalidHandle if no hints were requested. Result::ErrorInvalidRate if the hint was rate limited. Result::ErrorNoService if communication with the system service has failed. Result::ErrorUnavailable if the hint is not supported.
virtual oboe::Result oboe::AudioStream::notifyWorkloadSpike |
( |
bool | cpu, |
|
|
bool | gpu, |
|
|
const char * | debugName ) |
|
inlinevirtual |
Informs the framework of an upcoming one-off expensive frame for an audio callback bound to this session. This frame will be treated as not representative of the workload as a whole, and it will be discarded the purposes of load tracking. The user can specify whether the workload spike is expected to be on the CPU, GPU, or both.
Sending hints for both CPU and GPU counts as two separate hints for the purposes of the rate limiter.
This was introduced in Android API Level 36
- Parameters
-
cpu | Indicates if the workload spike is expected to affect the CPU. |
gpu | Indicates if the workload spike is expected to affect the GPU. |
debugName | A required string used to identify this specific hint during tracing. This debug string will only be held for the duration of the method, and can be safely discarded after. |
- Returns
- Result::OK on success. Result::ErrorInvalidState if the PerformanceHint was not enabled. Result::ErrorClosed if AdpfWrapper::open() was not called. Result::ErrorUnimplemented if the API is not supported. Result::ErrorInvalidHandle if no hints were requested. Result::ErrorInvalidRate if the hint was rate limited. Result::ErrorNoService if communication with the system service has failed. Result::ErrorUnavailable if the hint is not supported.
virtual Result oboe::AudioStream::release |
( |
| ) |
|
|
inlinevirtual |
Free the audio resources associated with a stream created by AAudioStreamBuilder_openStream().
AAudioStream_close() should be called at some point after calling this function.
After this call, the stream will be in AAUDIO_STREAM_STATE_CLOSING
This function is useful if you want to release the audio resources immediately, but still allow queries to the stream to occur from other threads. This often happens if you are monitoring stream progress from a UI thread.
NOTE: This function is only fully implemented for MMAP streams, which are low latency streams supported by some devices. On other "Legacy" streams some audio resources will still be in use and some callbacks may still be in process after this call.
Available in AAudio since API level 30. Returns Result::ErrorUnimplemented otherwise.
- Returns
- either Result::OK or an error.
virtual oboe::Result oboe::AudioStream::reportWorkload |
( |
int32_t | appWorkload | ) |
|
|
inlinevirtual |
Use this to give the performance manager more information about your workload. You can call this at the beginning of the callback when you figure out what your workload will be.
Call this if (1) you have called setPerformanceHintEnabled(true), and (2) you have a varying workload, and (3) you hear glitches when your workload suddenly increases.
This might happen when you go from a single note to a big chord on a synthesizer.
The workload can be in your own units. If you are synthesizing music then the workload could be the number of active voices. If your app is a game then it could be the number of sound effects. The units are arbitrary. They just have to be proportional to the estimated computational load. For example, if some of your voices take 20% more computation than a basic voice then assign 6 units to the complex voice and 5 units to the basic voice.
The performance hint code can use this as an advance warning that the callback duration will probably increase. Rather than wait for the long duration and possibly under-run, we can boost the CPU immediately before we start doing the calculations.
- Parameters
-
appWorkload | workload in application units, such as number of voices |
- Returns
- OK or an error such as ErrorInvalidState if the PerformanceHint was not enabled.
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().
This should only be used with Output streams. It will be ignored for Input streams because they are generally kept as empty as possible.
For OpenSL ES, this method only has an effect on output stream that do NOT use a callback. The blocking writes goes into a buffer in Oboe and the size of that buffer is controlled by this method.
- Parameters
-
requestedFrames | requested 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())
void oboe::AudioStream::setPerformanceHintEnabled |
( |
bool | enabled | ) |
|
|
inline |
Enable or disable a device specific CPU performance hint. Runtime benchmarks such as the callback duration may be used to speed up the CPU and improve real-time performance.
Note that this feature is device specific and may not be implemented. Also the benefits may vary by device.
The flag will be checked in the Oboe data callback. If it transitions from false to true then the PerformanceHint feature will be started. This only needs to be called once for each stream.
You may want to enable this if you have a dynamically changing workload and you notice that you are getting under-runs and glitches when your workload increases. This might happen, for example, if you suddenly go from playing one note to ten notes on a synthesizer.
Try the "CPU Load" test in OboeTester if you would like to experiment with this interactively.
On some devices, this may be implemented using the "ADPF" library.
- Parameters
-
enabled | true if you would like a performance boost, default is false |
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
-
inputState | The state we want to change away from. |
nextState | Pointer to a variable that will be set to the new state. |
timeoutNanoseconds | The maximum time to wait in nanoseconds. |
- Returns
- Result::OK or a Result::Error.