Skip to content

Commit 0a65ae3

Browse files
committed
Documentation updates
1 parent 429e502 commit 0a65ae3

5 files changed

Lines changed: 37 additions & 39 deletions

File tree

docs/FAQ.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ created with low latency using the AudioTrack.Builder method [`setPerformanceMod
99

1010
You can dynamically tune the latency of the stream just like in Oboe using [`setBufferSizeInFrames(int)`](https://developer.android.com/reference/android/media/AudioTrack.html#setBufferSizeInFrames(int))
1111
Also you can use blocking writes with the Java AudioTrack and still get a low latency stream.
12-
Oboe requires a callback to get a low latency stream and that does not work well with Java.
12+
Oboe requires a data callback to get a low latency stream and that does not work well with Java.
1313

1414
Note that [`AudioTrack.PERFORMANCE_MODE_LOW_LATENCY`](https://developer.android.com/reference/android/media/AudioTrack#PERFORMANCE_MODE_LOW_LATENCY) was added in API 26, For API 24 or 25 use [`AudioAttributes.FLAG_LOW_LATENCY`](https://developer.android.com/reference/kotlin/android/media/AudioAttributes#flag_low_latency). That was deprecated but will still work with later APIs.
1515

@@ -31,7 +31,7 @@ We have had several reports of this happening and are keen to understand the roo
3131
## I requested a stream with `PerformanceMode::LowLatency`, but didn't get it. Why not?
3232
Usually if you call `builder.setPerformanceMode(PerformanceMode::LowLatency)` and don't specify other stream properties you will get a `LowLatency` stream. The most common reasons for not receiving one are:
3333

34-
- You are opening an output stream and did not specify a **callback**.
34+
- You are opening an output stream and did not specify a **data callback**.
3535
- You requested a **sample** rate which does not match the audio device's native sample rate. For playback streams, this means the audio data you write into the stream must be resampled before it's sent to the audio device. For recording streams, the audio data must be resampled before you can read it. In both cases the resampling process (performed by the Android audio framework) adds latency and therefore providing a `LowLatency` stream is not possible. To avoid the resampler on API 26 and below you can specify a default value for the sample rate [as detailed here](https://github.com/google/oboe/blob/master/docs/GettingStarted.md#obtaining-optimal-latency). Or you can use the [new resampler](https://google.github.io/oboe/reference/classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027) in Oboe, which allows the lower level code to run at the optimal rate and provide lower latency.
3636
- If you request **AudioFormat::Float on an Input** stream before Android 9.0 then you will **not** get a FAST track. You need to either request AudioFormat::Int16 or [enable format conversion by Oboe](https://google.github.io/oboe/reference/classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2).
3737
- The audio **device** does not support `LowLatency` streams, for example Bluetooth.

docs/FullGuide.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ The following properties are guaranteed to be set. However, if these properties
111111
are unspecified, a default value will still be set, and should be queried by the
112112
appropriate accessor.
113113

114-
* callback
115114
* framesPerCallback
116115
* sampleRate
117116
* channelCount
@@ -149,7 +148,7 @@ builder), since it depends on run-time behavior.
149148
The actual size used may not be what was requested.
150149
Oboe or the underlyng API will limit the size between zero and the buffer capacity.
151150
It may also be limited further to reduce glitching on particular devices.
152-
This features is not supported when using OpenSL ES callbacks.
151+
This feature is not supported when using a callback with OpenSL ES.
153152

154153
Many of the stream's properties may vary (whether or not you set
155154
them) depending on the capabilities of the audio device and the Android device on
@@ -166,7 +165,8 @@ builder setting:
166165

167166
| AudioStreamBuilder set methods | AudioStream get methods |
168167
| :------------------------ | :----------------- |
169-
| `setCallback()` | `getCallback()` |
168+
| `setDataCallback()` | `getDataCallback()` |
169+
| `setErrorCallback()` | `getErrorCallback()` |
170170
| `setDirection()` | `getDirection()` |
171171
| `setSharingMode()` | `getSharingMode()` |
172172
| `setPerformanceMode()` | `getPerformanceMode()` |
@@ -222,7 +222,7 @@ transition:
222222
Note that you can only request pause or flush on an output stream:
223223

224224
These functions are asynchronous, and the state change doesn't happen
225-
immediately. When you request a state change, the stream moves toone of the
225+
immediately. When you request a state change, the stream moves to one of the
226226
corresponding transient states:
227227

228228
* Starting
@@ -276,7 +276,7 @@ while `waitForStateChange()` is running in another thread.
276276

277277
There are two ways to move data in or out of a stream.
278278
1) Read from or write directly to the stream.
279-
2) Specify a callback object that will get called when the stream is ready.
279+
2) Specify a data callback object that will get called when the stream is ready.
280280

281281
The callback technique offers the lowest latency performance because the callback code can run in a high priority thread.
282282
Also, attempting to open a low latency output stream without an audio callback (with the intent to use writes)
@@ -329,9 +329,8 @@ An audio stream can become disconnected at any time if one of these events happe
329329
When a stream is disconnected, it has the state "Disconnected" and calls to `write()` or other functions will return `Result::ErrorDisconnected`. When a stream is disconnected, all you can do is close it.
330330

331331
If you need to be informed when an audio device is disconnected, write a class
332-
which extends `AudioStreamCallback` and then register your class using `builder.setCallback(yourCallbackClass)`.
332+
which extends `AudioStreamErrorCallback` and then register your class using `builder.setErrorCallback(yourCallbackClass)`.
333333
If you register a callback, then it will automatically close the stream in a separate thread if the stream is disconnected.
334-
Note that registering this callback will enable callbacks for both data and errors. So `onAudioReady()` will be called. See the "high priority callback" section below.
335334

336335
Your callback can implement the following methods (called in a separate thread):
337336

@@ -343,26 +342,26 @@ Do not delete the stream or modify its stream state in this callback.
343342
During this callback, stream properties (those requested by the builder) can be queried, as well as frames written and read.
344343
The stream can be deleted at the end of this method (as long as it not referenced in other threads).
345344
Methods that reference the underlying stream should not be called (e.g. `getTimestamp()`, `getXRunCount()`, `read()`, `write()`, etc.).
346-
Opening a seperate stream is also a valid use of this callback, especially if the error received is `Error::Disconnected`.
345+
Opening a separate stream is also a valid use of this callback, especially if the error received is `Error::Disconnected`.
347346
However, it is important to note that the new audio device may have vastly different properties than the stream that was disconnected.
348347

349348

350349
## Optimizing performance
351350

352351
You can optimize the performance of an audio application by using special high-priority threads.
353352

354-
### Using a high priority callback
353+
### Using a high priority data callback
355354

356355
If your app reads or writes audio data from an ordinary thread, it may be preempted or experience timing jitter. This can cause audio glitches.
357356
Using larger buffers might guard against such glitches, but a large buffer also introduces longer audio latency.
358357
For applications that require low latency, an audio stream can use an asynchronous callback function to transfer data to and from your app.
359358
The callback runs in a high-priority thread that has better performance.
360359

361360
Your code can access the callback mechanism by implementing the virtual class
362-
`AudioStreamCallback`. The stream periodically executes `onAudioReady()` (the
361+
`AudioStreamDataCallback`. The stream periodically executes `onAudioReady()` (the
363362
callback function) to acquire the data for its next burst.
364363

365-
class AudioEngine : AudioStreamCallback {
364+
class AudioEngine : AudioStreamDataCallback {
366365
public:
367366
DataCallbackResult AudioEngine::onAudioReady(
368367
AudioStream *oboeStream,
@@ -375,15 +374,15 @@ callback function) to acquire the data for its next burst.
375374
bool AudioEngine::start() {
376375
...
377376
// register the callback
378-
streamBuilder.setCallback(this);
377+
streamBuilder.setDataCallback(this);
379378
}
380379
private:
381380
// application data
382381
Oscillator* oscillator_;
383382
}
384383

385384

386-
Note that the callback must be registered on the stream with `setCallback`. Any
385+
Note that the callback must be registered on the stream with `setDataCallback`. Any
387386
application-specific data (such as `oscillator_` in this case)
388387
can be included within the class itself.
389388

@@ -394,10 +393,10 @@ stream. The input stream is included in the class.
394393

395394
The callback does a non-blocking read from the input stream placing the data into the buffer of the output stream.
396395

397-
class AudioEngine : AudioStreamCallback {
396+
class AudioEngine : AudioStreamDataCallback {
398397
public:
399398

400-
oboe_data_callback_result_t AudioEngine::onAudioReady(
399+
DataCallbackResult AudioEngine::onAudioReady(
401400
AudioStream *oboeStream,
402401
void *audioData,
403402
int32_t numFrames) {
@@ -419,7 +418,7 @@ The callback does a non-blocking read from the input stream placing the data int
419418

420419
bool AudioEngine::start() {
421420
...
422-
streamBuilder.setCallback(this);
421+
streamBuilder.setDataCallback(this);
423422
}
424423

425424
void setRecordingStream(AudioStream *stream) {
@@ -433,7 +432,7 @@ The callback does a non-blocking read from the input stream placing the data int
433432

434433
Note that in this example it is assumed the input and output streams have the same number of channels, format and sample rate. The format of the streams can be mismatched - as long as the code handles the translations properly.
435434

436-
#### Callback do's and don'ts
435+
#### Data Callback - Do's and Don'ts
437436
You should never perform an operation which could block inside `onAudioReady`. Examples of blocking operations include:
438437

439438
- allocate memory using, for example, malloc() or new
@@ -466,15 +465,15 @@ This is useful for apps that are very interactive, such as games or keyboard syn
466465
If saving power is more important than low latency in your application, use `PerformanceMode::PowerSaving`.
467466
This is typical for apps that play back previously generated music, such as streaming audio or MIDI file players.
468467

469-
In the current version of Oboe, in order to achieve the lowest possible latency you must use the `PerformanceMode::LowLatency` performance mode along with a high-priority callback. Follow this example:
468+
In the current version of Oboe, in order to achieve the lowest possible latency you must use the `PerformanceMode::LowLatency` performance mode along with a high-priority data callback. Follow this example:
470469

471470
```
472471
// Create a callback object
473472
MyOboeStreamCallback myCallback;
474473
475474
// Create a stream builder
476475
AudioStreamBuilder builder;
477-
builder.setCallback(myCallback);
476+
builder.setDataCallback(myCallback);
478477
builder.setPerformanceMode(PerformanceMode::LowLatency);
479478
480479
// Use it to create the stream
@@ -497,8 +496,7 @@ These calls are also thread safe:
497496
* `convertToText()`
498497
* `AudioStream::get*()` except for `getTimestamp()` and `getState()`
499498

500-
<b>Note:</b> When a stream uses a callback function, it's safe to read/write from the callback thread while also closing the stream
501-
from the thread in which it is running.
499+
<b>Note:</b> When a stream uses an error callback, it's safe to read/write from the callback thread while also closing the stream from the thread in which it is running.
502500

503501

504502
## Code samples

docs/GettingStarted.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ The builder's set methods return a pointer to the builder. So they can be easily
149149
oboe::AudioStreamBuilder builder;
150150
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
151151
->setSharingMode(oboe::SharingMode::Exclusive)
152-
->setCallback(myCallback)
152+
->setDataCallback(myCallback)
153153
->setFormat(oboe::AudioFormat::Float);
154154
```
155155

156-
Define an `AudioStreamCallback` class to receive callbacks whenever the stream requires new data.
156+
Define an `AudioStreamDataCallback` class to receive callbacks whenever the stream requires new data.
157157

158-
class MyCallback : public oboe::AudioStreamCallback {
158+
class MyCallback : public oboe::AudioStreamDataCallback {
159159
public:
160160
oboe::DataCallbackResult
161161
onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
@@ -183,7 +183,7 @@ Declare your callback somewhere that it won't get deleted while you are using it
183183

184184
Supply this callback class to the builder:
185185

186-
builder.setCallback(&myCallback);
186+
builder.setDataCallback(&myCallback);
187187

188188
Declare a ManagedStream. Make sure it is declared in an appropriate scope (e.g.the member of a managing class). Avoid declaring it as a global.
189189
```
@@ -203,7 +203,7 @@ Note that this sample code uses the [logging macros from here](https://github.co
203203

204204
## Playing audio
205205
Check the properties of the created stream. If you did not specify a channelCount, sampleRate, or format then you need to
206-
query the stream to see what you got. The **format** property will dictate the `audioData` type in the `AudioStreamCallback::onAudioReady` callback. If you did specify any of those three properties then you will get what you requested.
206+
query the stream to see what you got. The **format** property will dictate the `audioData` type in the `AudioStreamDataCallback::onAudioReady` callback. If you did specify any of those three properties then you will get what you requested.
207207

208208
oboe::AudioFormat format = stream->getFormat();
209209
LOGI("AudioStream format is %s", oboe::convertToText(format));
@@ -266,7 +266,7 @@ closes the stream.
266266
#include <oboe/Oboe.h>
267267
#include <math.h>
268268
269-
class OboeSinePlayer: public oboe::AudioStreamCallback {
269+
class OboeSinePlayer: public oboe::AudioStreamDataCallback {
270270
public:
271271
272272
@@ -278,7 +278,7 @@ public:
278278
->setChannelCount(kChannelCount)
279279
->setSampleRate(kSampleRate)
280280
->setFormat(oboe::AudioFormat::Float)
281-
->setCallback(this)
281+
->setDataCallback(this)
282282
->openManagedStream(outStream);
283283
// Typically, start the stream after querying some stream information, as well as some input from the user
284284
outStream->requestStart();
@@ -314,8 +314,8 @@ private:
314314
```
315315
Note that this implementation computes sine values at run-time for simplicity,
316316
rather than pre-computing them.
317-
Additionally, best practice is to implement a separate callback class, rather
318-
than managing the stream and defining its callback in the same class.
317+
Additionally, best practice is to implement a separate data callback class, rather
318+
than managing the stream and defining its data callback in the same class.
319319
This class also automatically starts the stream upon construction. Typically,
320320
the stream is queried for information prior to being started (e.g. burst size),
321321
and started upon user input.

docs/OpenSLESMigration.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ OpenSL uses an audio engine object, created using `slCreateEngine`, to create ot
2626

2727
OpenSL uses audio player and audio recorder objects to communicate with audio devices. In Oboe an `AudioStream` is used.
2828

29-
In OpenSL the audio callback mechanism is a user-defined function which is called each time a buffer is enqueued. In Oboe you construct an `AudioStreamCallback` object, and its `onAudioReady` method is called each time audio data is ready to be read or written.
29+
In OpenSL the audio callback mechanism is a user-defined function which is called each time a buffer is enqueued. In Oboe you construct an `AudioStreamDataCallback` object, and its `onAudioReady` method is called each time audio data is ready to be read or written.
3030

3131
Here's a table which summarizes the object mappings:
3232

@@ -59,7 +59,7 @@ Here's a table which summarizes the object mappings:
5959
<tr>
6060
<td>Callback function
6161
</td>
62-
<td><code>AudioStreamCallback::onAudioReady</code>
62+
<td><code>AudioStreamDataCallback::onAudioReady</code>
6363
</td>
6464
</tr>
6565
</table>
@@ -84,7 +84,7 @@ DataCallbackResult onAudioReady(
8484
```
8585

8686

87-
You supply your implementation of `onAudioReady` when building the audio stream by constructing an `AudioStreamCallback` object. [Here's an example.](https://github.com/google/oboe/blob/master/docs/GettingStarted.md#creating-an-audio-stream)
87+
You supply your implementation of `onAudioReady` when building the audio stream by constructing an `AudioStreamDataCallback` object. [Here's an example.](https://github.com/google/oboe/blob/master/docs/GettingStarted.md#creating-an-audio-stream)
8888

8989

9090
### Buffer sizes
@@ -124,7 +124,7 @@ However, you may want to specify some properties. These are set using the `Audio
124124

125125
OpenSL has no mechanism, other than stopping callbacks, to indicate that an audio device has been disconnected - for example, when headphones are unplugged.
126126

127-
In Oboe, you can be notified of stream disconnection by overriding one of the `onError` methods in `AudioStreamCallback`. This allows you to clean up any resources associated with the audio stream and create a new stream with optimal properties for the current audio device ([more info](https://github.com/google/oboe/blob/master/docs/FullGuide.md#disconnected-audio-stream)).
127+
In Oboe, you can be notified of stream disconnection by overriding one of the `onError` methods in `AudioStreamErrorCallback`. This allows you to clean up any resources associated with the audio stream and create a new stream with optimal properties for the current audio device ([more info](https://github.com/google/oboe/blob/master/docs/FullGuide.md#disconnected-audio-stream)).
128128

129129

130130
# Unsupported features
@@ -162,8 +162,8 @@ Oboe does **not** support the following features:
162162

163163
* Replace your audio player or recorder with an `AudioStream` created using an `AudioStreamBuilder`.
164164
* Use your value for `numBuffers` to set the audio stream's buffer size as a multiple of the burst size. For example: `audioStream.setBufferSizeInFrames(audioStream.getFramesPerBurst * numBuffers)`.
165-
* Create an `AudioStreamCallback` object and move your OpenSL callback code inside the `onAudioReady` method.
166-
* Handle stream disconnect events by overriding one of the `AudioStreamCallback::onError` methods.
165+
* Create an `AudioStreamDataCallback` object and move your OpenSL callback code inside the `onAudioReady` method.
166+
* Handle stream disconnect events by creating an `AudioStreamErrorCallback` object and overriding one of its `onError` methods.
167167
* Pass sensible default sample rate and buffer size values to Oboe from `AudioManager` [using this method](https://github.com/google/oboe/blob/master/docs/GettingStarted.md#obtaining-optimal-latency) so that your app is still performant on older devices.
168168

169169
For more information please read the [Full Guide to Oboe](https://github.com/google/oboe/blob/master/docs/FullGuide.md).

docs/notes/disconnect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ When Oboe is using **AAudio**, and a headset is plugged in or out, then
99
the stream is no longer available and becomes "disconnected".
1010
The app should then be notified in one of two ways.
1111

12-
1) If the app is using a callback then the AudioStreamCallback object will be called.
12+
1) If the app is using an error callback then the AudioStreamErrorCallback methods will be called.
1313
It will launch a thread, which will call onErrorBeforeClose().
1414
Then it stops and closes the stream.
1515
Then onErrorAfterClose() will be called.

0 commit comments

Comments
 (0)