Upgrade oboe to 69c8eb17cf21621635634a111360d599360755a6 am: 9fbc1f3456

Original change: https://android-review.googlesource.com/c/platform/external/oboe/+/1514953

Change-Id: I8fc55ec42dfbc922cde3237f1b7128ea69c96168
diff --git a/Doxyfile b/Doxyfile
index 12b0b59..f0e0be3 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -38,7 +38,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.2
+PROJECT_NUMBER         = 1.5
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/METADATA b/METADATA
index 263e9f7..4160dfe 100644
--- a/METADATA
+++ b/METADATA
@@ -5,10 +5,10 @@
     type: GIT
     value: "https://github.com/google/oboe"
   }
-  version: "52aca5741e256f2a51594ec818d1991de05cbfcd"
+  version: "69c8eb17cf21621635634a111360d599360755a6"
   last_upgrade_date {
     year: 2020
-    month: 10
-    day: 28
+    month: 11
+    day: 30
   }
 }
diff --git a/README.md b/README.md
index 85033d1..a36ad6b 100644
--- a/README.md
+++ b/README.md
@@ -15,12 +15,13 @@
 ## Requirements
 To build Oboe you'll need a compiler which supports C++14 and the Android header files. The easiest way to obtain these is by downloading the Android NDK r17 or above. It can be installed using Android Studio's SDK manager, or via [direct download](https://developer.android.com/ndk/downloads/).
 
-## API Documentation
+## Documentation
 - [Getting Started Guide](docs/GettingStarted.md)
 - [Full Guide to Oboe](docs/FullGuide.md)
 - [API reference](https://google.github.io/oboe/reference)
 - [Tech Notes](docs/notes/)
 - [History of Audio features/bugs by Android version](docs/AndroidAudioHistory.md)
+- [Migration guide for apps using OpenSL ES](docs/OpenSLESMigration.md)
 - [Frequently Asked Questions](docs/FAQ.md) (FAQ)
 - [Our roadmap](https://github.com/google/oboe/milestones) - Vote on a feature/issue by adding a thumbs up to the first comment.
 
diff --git a/apps/OboeTester/app/build.gradle b/apps/OboeTester/app/build.gradle
index 26820d7..dd01a16 100644
--- a/apps/OboeTester/app/build.gradle
+++ b/apps/OboeTester/app/build.gradle
@@ -7,8 +7,8 @@
         minSdkVersion 23
         targetSdkVersion 28
         // Also update the versions in the AndroidManifest.xml file.
-        versionCode 38
-        versionName "1.5.30"
+        versionCode 41
+        versionName "1.5.33"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         externalNativeBuild {
             cmake {
diff --git a/apps/OboeTester/app/src/main/AndroidManifest.xml b/apps/OboeTester/app/src/main/AndroidManifest.xml
index 7c1c783..d158c45 100644
--- a/apps/OboeTester/app/src/main/AndroidManifest.xml
+++ b/apps/OboeTester/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.sample.oboe.manualtest"
-    android:versionCode="38"
-    android:versionName="1.5.30">
+    android:versionCode="41"
+    android:versionName="1.5.33">
     <!-- versionCode and versionName also have to be updated in build.gradle -->
 
     <uses-feature android:name="android.hardware.microphone" android:required="true" />
@@ -92,6 +92,12 @@
             android:screenOrientation="portrait">
         </activity>
 
+        <activity
+            android:name="com.google.sample.oboe.manualtest.DeviceReportActivity"
+            android:label="@string/title_report_devices"
+            android:screenOrientation="portrait">
+        </activity>
+
         <service
             android:name="com.google.sample.oboe.manualtest.AudioMidiTester"
             android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
diff --git a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp
index 8f8cd74..7809206 100644
--- a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp
+++ b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.cpp
@@ -130,7 +130,7 @@
     if (mUseCallback) {
         LOGD("ActivityContext::open() set callback to use oboeCallbackProxy, callback size = %d",
              callbackSize);
-        builder.setCallback(&oboeCallbackProxy);
+        builder.setDataCallback(&oboeCallbackProxy);
         builder.setFramesPerCallback(callbackSize);
     }
 }
@@ -507,7 +507,6 @@
     mSinkFloat->pullReset();
     mSinkI16->pullReset();
 
-    sawPingGenerator.setEnabled(false);
     configureStreamGateway();
 }
 
diff --git a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
index ad774fb..95df984 100644
--- a/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
+++ b/apps/OboeTester/app/src/main/cpp/NativeAudioContext.h
@@ -192,6 +192,7 @@
 public:
 
     ActivityContext() {}
+
     virtual ~ActivityContext() = default;
 
     oboe::AudioStream *getStream(int32_t streamIndex) {
@@ -271,8 +272,11 @@
         return 0.0;
     }
 
-    virtual void setEnabled(bool enabled) {
-    }
+    /**
+     * Trigger a sound or impulse.
+     * @param enabled
+     */
+    virtual void trigger() {}
 
     bool isMMapUsed(int32_t streamIndex);
 
@@ -285,7 +289,11 @@
     }
 
     oboe::Result getLastErrorCallbackResult() {
-        return oboeCallbackProxy.getLastErrorCallbackResult();
+        oboe::AudioStream *stream = getOutputStream();
+        if (stream == nullptr) {
+            stream = getInputStream();
+        }
+        return stream ? oboe::Result::ErrorNull : stream->getLastErrorCallbackResult();
     }
 
     int32_t getFramesPerCallback() {
@@ -468,8 +476,8 @@
 
     void configureForStart() override;
 
-    virtual void setEnabled(bool enabled) override {
-        sawPingGenerator.setEnabled(enabled);
+    virtual void trigger() override {
+        sawPingGenerator.trigger();
     }
 
     SawPingGenerator             sawPingGenerator;
diff --git a/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.cpp b/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.cpp
index f16e861..14f8234 100644
--- a/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.cpp
+++ b/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.cpp
@@ -79,18 +79,3 @@
 
     return callbackResult;
 }
-
-void OboeStreamCallbackProxy::onErrorBeforeClose(oboe::AudioStream *audioStream, oboe::Result error) {
-    LOGD("OboeStreamCallbackProxy::%s(%p, %d) called", __func__, audioStream, error);
-    mErrorCallbackResult = error;
-    if (mCallback != nullptr) {
-        mCallback->onErrorBeforeClose(audioStream, error);
-    }
-}
-
-void OboeStreamCallbackProxy::onErrorAfterClose(oboe::AudioStream *audioStream, oboe::Result  error) {
-    LOGD("OboeStreamCallbackProxy::%s(%p, %d) called", __func__, audioStream, error);
-    if (mCallback != nullptr) {
-        mCallback->onErrorAfterClose(audioStream, error);
-    }
-}
diff --git a/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.h b/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.h
index e9cd4fe..9bfeaca 100644
--- a/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.h
+++ b/apps/OboeTester/app/src/main/cpp/OboeStreamCallbackProxy.h
@@ -22,7 +22,7 @@
 
 #include "oboe/Oboe.h"
 
-class OboeStreamCallbackProxy : public oboe::AudioStreamCallback {
+class OboeStreamCallbackProxy : public oboe::AudioStreamDataCallback {
 public:
 
     void setCallback(oboe::AudioStreamCallback *callback) {
@@ -54,10 +54,6 @@
             void *audioData,
             int numFrames) override;
 
-    void onErrorBeforeClose(oboe::AudioStream *audioStream, oboe::Result error) override;
-
-    void onErrorAfterClose(oboe::AudioStream *audioStream, oboe::Result error) override;
-
     /**
      * Specify the amount of artificial workload that will waste CPU cycles
      * and increase the CPU load.
@@ -77,10 +73,6 @@
 
     static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC);
 
-    oboe::Result getLastErrorCallbackResult() {
-        return mErrorCallbackResult;
-    }
-
 private:
     static constexpr int32_t   kWorkloadScaler = 500;
     double                     mWorkload = 0.0;
@@ -90,7 +82,6 @@
     static bool                mCallbackReturnStop;
     int64_t                    mCallbackCount = 0;
     std::atomic<int32_t>       mFramesPerCallback{0};
-    oboe::Result               mErrorCallbackResult = oboe::Result::OK;
 };
 
 
diff --git a/apps/OboeTester/app/src/main/cpp/SawPingGenerator.cpp b/apps/OboeTester/app/src/main/cpp/SawPingGenerator.cpp
index 80763af..3220df2 100644
--- a/apps/OboeTester/app/src/main/cpp/SawPingGenerator.cpp
+++ b/apps/OboeTester/app/src/main/cpp/SawPingGenerator.cpp
@@ -30,6 +30,11 @@
 
 SawPingGenerator::~SawPingGenerator() { }
 
+void SawPingGenerator::reset() {
+    FlowGraphNode::reset();
+    mAcknowledgeCount.store(mRequestCount.load());
+}
+
 int32_t SawPingGenerator::onProcess(int numFrames) {
 
     const float *frequencies = frequency.getBuffer();
@@ -58,11 +63,7 @@
     return numFrames;
 }
 
-void SawPingGenerator::setEnabled(bool enabled) {
-    if (enabled) {
-        mRequestCount++;
-    } else {
-        mAcknowledgeCount.store(mRequestCount.load());
-    }
+void SawPingGenerator::trigger() {
+    mRequestCount++;
 }
 
diff --git a/apps/OboeTester/app/src/main/cpp/SawPingGenerator.h b/apps/OboeTester/app/src/main/cpp/SawPingGenerator.h
index 981bad6..f1f5e5b 100644
--- a/apps/OboeTester/app/src/main/cpp/SawPingGenerator.h
+++ b/apps/OboeTester/app/src/main/cpp/SawPingGenerator.h
@@ -32,7 +32,9 @@
 
     int32_t onProcess(int numFrames) override;
 
-    void setEnabled(bool enabled);
+    void trigger();
+
+    void reset() override;
 
 private:
     std::atomic<int> mRequestCount; // external thread increments this to request a beep
diff --git a/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp b/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
index 817d98b..09c273f 100644
--- a/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
+++ b/apps/OboeTester/app/src/main/cpp/jni-bridge.cpp
@@ -77,7 +77,7 @@
 // ================= OboeAudioOutputStream ================================
 
 JNIEXPORT void JNICALL
-Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_setToneEnabled(JNIEnv *env, jobject, jboolean);
+Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_trigger(JNIEnv *env, jobject);
 JNIEXPORT void JNICALL
 Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_setToneType(JNIEnv *env, jobject, jint);
 JNIEXPORT void JNICALL
@@ -381,8 +381,12 @@
 
 JNIEXPORT jint JNICALL
 Java_com_google_sample_oboe_manualtest_OboeAudioStream_getLastErrorCallbackResult(
-        JNIEnv *env, jobject) {
-    return (jint) engine.getCurrentActivity()->getLastErrorCallbackResult();
+        JNIEnv *env, jobject, jint streamIndex) {
+    oboe::AudioStream *oboeStream = engine.getCurrentActivity()->getStream(streamIndex);
+    if (oboeStream != nullptr) {
+        return (jint) oboeStream->getLastErrorCallbackResult();
+    }
+    return 0;
 }
 
 JNIEXPORT jdouble JNICALL
@@ -465,15 +469,9 @@
 // ================= OboeAudioOutputStream ================================
 
 JNIEXPORT void JNICALL
-Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_setToneEnabled(
-        JNIEnv *env, jobject, jboolean enabled) {
-    engine.getCurrentActivity()->setEnabled(enabled);
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_setToneType(
-        JNIEnv *env, jobject, jint toneType) {
-// FIXME    engine.getCurrentActivity()->setToneType(toneType);
+Java_com_google_sample_oboe_manualtest_OboeAudioOutputStream_trigger(
+        JNIEnv *env, jobject) {
+    engine.getCurrentActivity()->trigger();
 }
 
 JNIEXPORT void JNICALL
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceInfoConverter.java b/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceInfoConverter.java
index f6e0afe..f736667 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceInfoConverter.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceInfoConverter.java
@@ -17,7 +17,7 @@
 
 import android.media.AudioDeviceInfo;
 
-class AudioDeviceInfoConverter {
+public class AudioDeviceInfoConverter {
 
     /**
      * Converts an {@link AudioDeviceInfo} object into a human readable representation
@@ -25,7 +25,7 @@
      * @param adi The AudioDeviceInfo object to be converted to a String
      * @return String containing all the information from the AudioDeviceInfo object
      */
-    static String toString(AudioDeviceInfo adi){
+    public static String toString(AudioDeviceInfo adi){
 
         StringBuilder sb = new StringBuilder();
         sb.append("Id: ");
@@ -62,7 +62,7 @@
         sb.append("\nSample Rates: ");
         int[] sampleRates = adi.getSampleRates();
         sb.append(intArrayToString(sampleRates));
-
+        sb.append("\n");
         return sb.toString();
     }
 
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceListEntry.java b/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceListEntry.java
index 15f3e23..d79768e 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceListEntry.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/audio_device/AudioDeviceListEntry.java
@@ -84,7 +84,9 @@
             if (directionType == AudioManager.GET_DEVICES_ALL ||
                     (directionType == AudioManager.GET_DEVICES_OUTPUTS && info.isSink()) ||
                     (directionType == AudioManager.GET_DEVICES_INPUTS && info.isSource())) {
-                listEntries.add(new AudioDeviceListEntry(info.getId(), info.getProductName() + " " +
+                listEntries.add(new AudioDeviceListEntry(info.getId(),
+                        info.getId() + ": " +
+                                info.getProductName() + " " +
                                 AudioDeviceInfoConverter.typeToString(info.getType())));
             }
         }
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AnalyzerActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AnalyzerActivity.java
index 712177b..443a258 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AnalyzerActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AnalyzerActivity.java
@@ -45,6 +45,24 @@
 
     private static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 1001;
 
+    public static final String KEY_IN_SHARING = "in_sharing";
+    public static final String KEY_OUT_SHARING = "out_sharing";
+    public static final String VALUE_SHARING_EXCLUSIVE = "exclusive";
+    public static final String VALUE_SHARING_SHARED = "shared";
+
+    public static final String KEY_IN_PERF = "in_perf";
+    public static final String KEY_OUT_PERF = "out_perf";
+    public static final String VALUE_PERF_LOW_LATENCY = "lowlat";
+    public static final String VALUE_PERF_POWERSAVE = "powersave";
+    public static final String VALUE_PERF_NONE = "none";
+
+    public static final String KEY_IN_CHANNELS = "in_channels";
+    public static final String KEY_OUT_CHANNELS = "out_channels";
+    public static final int VALUE_DEFAULT_CHANNELS = 2;
+
+    public static final String KEY_SAMPLE_RATE = "sample_rate";
+    public static final int VALUE_DEFAULT_SAMPLE_RATE = 48000;
+
     protected static final String KEY_FILE_NAME = "file";
     protected static final String KEY_BUFFER_BURSTS = "buffer_bursts";
 
@@ -179,11 +197,32 @@
         }
     }
 
-    void configureStreamsFromBundleForApi(Bundle bundle) {
+    private int getPerfFromText(String text) {
+        if (VALUE_PERF_NONE.equals(text)) {
+            return StreamConfiguration.PERFORMANCE_MODE_NONE;
+        } else if (VALUE_PERF_POWERSAVE.equals(text)) {
+            return StreamConfiguration.PERFORMANCE_MODE_POWER_SAVING;
+        } else {
+            return StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY;
+        }
+    }
+
+    private int getSharingFromText(String text) {
+        if (VALUE_SHARING_SHARED.equals(text)) {
+            return StreamConfiguration.SHARING_MODE_SHARED;
+        } else {
+            return StreamConfiguration.SHARING_MODE_EXCLUSIVE;
+        }
+    }
+
+    void configureStreamsFromBundle(Bundle bundle) {
         // Configure settings
         StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
         StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
 
+        requestedInConfig.reset();
+        requestedOutConfig.reset();
+
         // OpenSL ES or AAudio API
         String text = bundle.getString(KEY_IN_API, VALUE_UNSPECIFIED);
         int audioApi = getApiFromText(text);
@@ -191,6 +230,31 @@
         text = bundle.getString(KEY_OUT_API, VALUE_UNSPECIFIED);
         audioApi = getApiFromText(text);
         requestedOutConfig.setNativeApi(audioApi);
+
+        // channnels
+        int inChannels = bundle.getInt(KEY_IN_CHANNELS, VALUE_DEFAULT_CHANNELS);
+        requestedInConfig.setChannelCount(inChannels);
+        int outChannels = bundle.getInt(KEY_OUT_CHANNELS, VALUE_DEFAULT_CHANNELS);
+        requestedOutConfig.setChannelCount(outChannels);
+
+        // performance mode
+        text = bundle.getString(KEY_IN_PERF, VALUE_PERF_LOW_LATENCY);
+        int perfMode = getPerfFromText(text);
+        requestedInConfig.setPerformanceMode(perfMode);
+        text = bundle.getString(KEY_OUT_PERF, VALUE_PERF_LOW_LATENCY);
+        perfMode = getPerfFromText(text);
+        requestedOutConfig.setPerformanceMode(perfMode);
+
+        int sampleRate = bundle.getInt(KEY_SAMPLE_RATE, VALUE_DEFAULT_SAMPLE_RATE);
+        requestedInConfig.setSampleRate(sampleRate);
+        requestedOutConfig.setSampleRate(sampleRate);
+
+        text = bundle.getString(KEY_IN_SHARING, VALUE_SHARING_EXCLUSIVE);
+        int sharingMode = getSharingFromText(text);
+        requestedInConfig.setSharingMode(sharingMode);
+        text = bundle.getString(KEY_OUT_SHARING, VALUE_SHARING_EXCLUSIVE);
+        sharingMode = getSharingFromText(text);
+        requestedOutConfig.setSharingMode(sharingMode);
     }
 
     void writeTestResultIfPermitted(String resultString) {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioMidiTester.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioMidiTester.java
index 3cb57d8..0cb920c 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioMidiTester.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioMidiTester.java
@@ -129,7 +129,7 @@
     }
 
     private void noteOn(byte b) {
-        setEnabled(true);
+        trigger();
         fireNoteOn(b);
     }
 
@@ -139,9 +139,7 @@
         }
     }
 
-    private void noteOff(byte b) {
-        setEnabled(false);
-    }
+    private void noteOff(byte b) {}
 
     @Override
     public MidiReceiver[] onGetInputPortReceivers() {
@@ -155,9 +153,9 @@
         }
     }
 
-    public void setEnabled(boolean checked) {
-        mAudioOutputTester.setEnabled(checked);
-        if (checked && mRecordEnabled) {
+    public void trigger() {
+        mAudioOutputTester.trigger();
+        if (mRecordEnabled) {
             // schedule an analysis to start in the near future
             int numSamples = (int) (mRecorder.getSampleRate() * ANALYSIS_TIME_DELAY);
             Runnable task = new Runnable() {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
index 8185b48..1e90a75 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AudioOutputTester.java
@@ -36,18 +36,11 @@
         Log.i(TapToToneActivity.TAG, "create OboeAudioOutputStream ---------");
         mOboeAudioOutputStream = new OboeAudioOutputStream();
         mCurrentAudioStream = mOboeAudioOutputStream;
-        setToneType(OboeAudioOutputStream.TONE_TYPE_SINE);
-        setEnabled(false);
         requestedConfiguration.setDirection(StreamConfiguration.DIRECTION_OUTPUT);
     }
 
-    public void setToneType(int index) {
-        Log.i(TapToToneActivity.TAG, "setToneType(" + index + ")");
-        mOboeAudioOutputStream.setToneType(index);
-    }
-
-    public void setEnabled(boolean flag) {
-        mOboeAudioOutputStream.setToneEnabled(flag);
+    public void trigger() {
+        mOboeAudioOutputStream.trigger();
     }
 
     public void setChannelEnabled(int channelIndex, boolean enabled)  {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/DeviceReportActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/DeviceReportActivity.java
new file mode 100644
index 0000000..2f59acb
--- /dev/null
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/DeviceReportActivity.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.sample.oboe.manualtest;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.MicrophoneInfo;
+import android.os.Bundle;
+import android.text.method.ScrollingMovementMethod;
+import android.widget.TextView;
+
+import com.google.sample.audio_device.AudioDeviceInfoConverter;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Guide the user through a series of tests plugging in and unplugging a headset.
+ * Print a summary at the end of any failures.
+ */
+public class DeviceReportActivity extends Activity {
+
+    class MyAudioDeviceCallback extends AudioDeviceCallback {
+        private HashMap<Integer, AudioDeviceInfo> mDevices
+                = new HashMap<Integer, AudioDeviceInfo>();
+
+        @Override
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            for (AudioDeviceInfo info : addedDevices) {
+                mDevices.put(info.getId(), info);
+            }
+            reportDeviceInfo(mDevices.values());
+        }
+
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            for (AudioDeviceInfo info : removedDevices) {
+                mDevices.remove(info.getId());
+            }
+            reportDeviceInfo(mDevices.values());
+        }
+    }
+
+    MyAudioDeviceCallback mDeviceCallback = new MyAudioDeviceCallback();
+    private TextView      mAutoTextView;
+    private AudioManager  mAudioManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_device_report);
+        mAutoTextView = (TextView) findViewById(R.id.text_log);
+        mAutoTextView.setMovementMethod(new ScrollingMovementMethod());
+
+        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        addAudioDeviceCallback();
+    }
+
+    @Override
+    protected void onStop() {
+        removeAudioDeviceCallback();
+        super.onStop();
+    }
+
+    @TargetApi(23)
+    private void addAudioDeviceCallback(){
+        // Note that we will immediately receive a call to onDevicesAdded with the list of
+        // devices which are currently connected.
+        mAudioManager.registerAudioDeviceCallback(mDeviceCallback, null);
+    }
+
+    @TargetApi(23)
+    private void removeAudioDeviceCallback(){
+        mAudioManager.unregisterAudioDeviceCallback(mDeviceCallback);
+    }
+
+    private void reportDeviceInfo(Collection<AudioDeviceInfo> devices) {
+        logClear();
+        StringBuffer report = new StringBuffer();
+        report.append("Device Report:\n");
+        for (AudioDeviceInfo deviceInfo : devices) {
+            report.append("\n==== Device =================== " + deviceInfo.getId() + "\n");
+            String item = AudioDeviceInfoConverter.toString(deviceInfo);
+            report.append(item);
+        }
+        report.append(reportAllMicrophones());
+        report.append(reportExtraDeviceInfo());
+        log(report.toString());
+    }
+
+    public String reportAllMicrophones() {
+        StringBuffer report = new StringBuffer();
+        report.append("\n############################");
+        report.append("\nMicrophone Report:\n");
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
+            try {
+                List<MicrophoneInfo> micList = mAudioManager.getMicrophones();
+                for (MicrophoneInfo micInfo : micList) {
+                    String micItem = MicrophoneInfoConverter.reportMicrophoneInfo(micInfo);
+                    report.append(micItem);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+                return e.getMessage();
+            }
+        } else {
+            report.append("\nMicrophoneInfo not available on V" + android.os.Build.VERSION.SDK_INT);
+        }
+        return report.toString();
+    }
+
+    private String reportExtraDeviceInfo() {
+        StringBuffer report = new StringBuffer();
+        report.append("\n\n############################");
+        report.append("\nExtras:");
+        String unprocessedSupport = mAudioManager.getParameters(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED);
+        report.append("\nSUPPORT_UNPROCESSED  : " + ((unprocessedSupport == null) ?  "null" : "yes"));
+
+        report.append("\nProAudio Feature     : "
+            + getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_PRO));
+        report.append("\nLowLatency Feature   : "
+                + getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY));
+        report.append("\nMIDI Feature         : "
+                + getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI));
+        report.append("\nUSB Host Feature     : "
+                + getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_HOST));
+        report.append("\nUSB Accessory Feature: "
+                + getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY));
+
+        return report.toString();
+    }
+
+    // Write to scrollable TextView
+    private void log(final String text) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mAutoTextView.append(text);
+                mAutoTextView.append("\n");
+            }
+        });
+    }
+
+    private void logClear() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mAutoTextView.setText("");
+            }
+        });
+    }
+
+}
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MainActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MainActivity.java
index ea0b48a..099774e 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MainActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MainActivity.java
@@ -251,6 +251,12 @@
         startActivity(intent);
     }
 
+    public void onLaunchTestDeviceReport(View view) {
+        updateCallbackSize();
+        Intent intent = new Intent(this, DeviceReportActivity.class);
+        startActivity(intent);
+    }
+
     public void onUseCallbackClicked(View view) {
         CheckBox checkBox = (CheckBox) view;
         OboeAudioStream.setUseCallback(checkBox.isChecked());
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
index 8576acc..d60f4b3 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
@@ -20,7 +20,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
@@ -28,26 +27,8 @@
 
 public class ManualGlitchActivity extends GlitchActivity {
 
-    public static final String KEY_IN_PERF = "in_perf";
-    public static final String KEY_OUT_PERF = "out_perf";
-    public static final String VALUE_PERF_LOW_LATENCY = "lowlat";
-    public static final String VALUE_PERF_POWERSAVE = "powersave";
-    public static final String VALUE_PERF_NONE = "none";
-
-    public static final String KEY_IN_SHARING = "in_sharing";
-    public static final String KEY_OUT_SHARING = "out_sharing";
-    public static final String VALUE_SHARING_EXCLUSIVE = "exclusive";
-    public static final String VALUE_SHARING_SHARED = "shared";
-
-    public static final String KEY_SAMPLE_RATE = "sample_rate";
-    public static final int VALUE_DEFAULT_SAMPLE_RATE = 48000;
-
     public static final String KEY_IN_PRESET = "in_preset";
 
-    public static final String KEY_IN_CHANNELS = "in_channels";
-    public static final String KEY_OUT_CHANNELS = "out_channels";
-    public static final int VALUE_DEFAULT_CHANNELS = 2;
-
     public static final String KEY_DURATION = "duration";
     public static final int VALUE_DEFAULT_DURATION = 10;
 
@@ -150,68 +131,22 @@
         }
     }
 
-    private int getPerfFromText(String text) {
-        if (VALUE_PERF_NONE.equals(text)) {
-            return StreamConfiguration.PERFORMANCE_MODE_NONE;
-        } else if (VALUE_PERF_POWERSAVE.equals(text)) {
-            return StreamConfiguration.PERFORMANCE_MODE_POWER_SAVING;
-        } else {
-            return StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY;
-        }
-    }
-
-    private int getSharingFromText(String text) {
-        if (VALUE_SHARING_SHARED.equals(text)) {
-            return StreamConfiguration.SHARING_MODE_SHARED;
-        } else {
-            return StreamConfiguration.SHARING_MODE_EXCLUSIVE;
-        }
-    }
-
     void configureStreamsFromBundle(Bundle bundle) {
+        // Extract common parameters
+        super.configureStreamsFromBundle(bundle);
 
-        // Configure settings
         StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
         StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
 
-        requestedInConfig.reset();
-        requestedOutConfig.reset();
-
-        configureStreamsFromBundleForApi(bundle);
-
-        // Extract parameters from the bundle.
-        String text = bundle.getString(KEY_IN_PERF, VALUE_PERF_LOW_LATENCY);
-        int perfMode = getPerfFromText(text);
-        requestedInConfig.setPerformanceMode(perfMode);
-
-        text = bundle.getString(KEY_OUT_PERF, VALUE_PERF_LOW_LATENCY);
-        perfMode = getPerfFromText(text);
-        requestedOutConfig.setPerformanceMode(perfMode);
-
-        text = bundle.getString(KEY_IN_SHARING, VALUE_SHARING_EXCLUSIVE);
-        int sharingMode = getSharingFromText(text);
-        requestedInConfig.setSharingMode(sharingMode);
-        text = bundle.getString(KEY_OUT_SHARING, VALUE_SHARING_EXCLUSIVE);
-        sharingMode = getSharingFromText(text);
-        requestedOutConfig.setSharingMode(sharingMode);
-
-        int sampleRate = bundle.getInt(KEY_SAMPLE_RATE, VALUE_DEFAULT_SAMPLE_RATE);
-        requestedInConfig.setSampleRate(sampleRate);
-        requestedOutConfig.setSampleRate(sampleRate);
-
+        // Extract custom parameters from the bundle.
         float tolerance = bundle.getFloat(KEY_TOLERANCE, DEFAULT_TOLERANCE);
         setToleranceFader(tolerance);
         setTolerance(tolerance);
         mTolerance = tolerance;
 
-        int inChannels = bundle.getInt(KEY_IN_CHANNELS, VALUE_DEFAULT_CHANNELS);
-        requestedInConfig.setChannelCount(inChannels);
-        int outChannels = bundle.getInt(KEY_OUT_CHANNELS, VALUE_DEFAULT_CHANNELS);
-        requestedOutConfig.setChannelCount(outChannels);
-
         String defaultText = StreamConfiguration.convertInputPresetToText(
                 StreamConfiguration.INPUT_PRESET_VOICE_RECOGNITION);
-        text = bundle.getString(KEY_IN_PRESET, defaultText);
+        String text = bundle.getString(KEY_IN_PRESET, defaultText);
         int inputPreset = StreamConfiguration.convertTextToInputPreset(text);
         requestedInConfig.setInputPreset(inputPreset);
     }
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MicrophoneInfoConverter.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MicrophoneInfoConverter.java
new file mode 100644
index 0000000..3494c0b
--- /dev/null
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/MicrophoneInfoConverter.java
@@ -0,0 +1,73 @@
+package com.google.sample.oboe.manualtest;
+
+import android.media.MicrophoneInfo;
+import android.util.Pair;
+
+import java.util.List;
+
+public class MicrophoneInfoConverter {
+
+    static String convertDirectionality(int directionality) {
+        switch(directionality) {
+            case MicrophoneInfo.DIRECTIONALITY_BI_DIRECTIONAL:
+                return "Bidirectional";
+            case MicrophoneInfo.DIRECTIONALITY_OMNI:
+                return "Omni";
+            case MicrophoneInfo.DIRECTIONALITY_CARDIOID:
+                return "Cardioid";
+            case MicrophoneInfo.DIRECTIONALITY_SUPER_CARDIOID:
+                return "SuperCardioid";
+            case MicrophoneInfo.DIRECTIONALITY_HYPER_CARDIOID:
+                return "HyperCardioid";
+            default:
+                return "Unknown";
+        }
+    }
+
+    static String convertLocation(int location) {
+        switch(location) {
+            case MicrophoneInfo.LOCATION_MAINBODY:
+                return "Main Body";
+            case MicrophoneInfo.LOCATION_MAINBODY_MOVABLE:
+                return "Main Body Movable";
+            case MicrophoneInfo.LOCATION_PERIPHERAL:
+                return "Peripheral";
+            default:
+                return "Unknown";
+        }
+    }
+
+    static String convertCoordinates(MicrophoneInfo.Coordinate3F coordinates) {
+        if (coordinates == MicrophoneInfo.POSITION_UNKNOWN) return "Unknown";
+        return String.format("{ %6.4g, %5.3g, %5.3g }",
+                coordinates.x, coordinates.y, coordinates.z);
+    }
+
+    public static String reportMicrophoneInfo(MicrophoneInfo micInfo) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("\n==== Microphone ========= " + micInfo.getId());
+        sb.append("\nAddress    : " + micInfo.getAddress());
+        sb.append("\nDescription: " + micInfo.getDescription());
+        sb.append("\nDirection  : " + convertDirectionality(micInfo.getDirectionality()));
+        sb.append("\nLocation   : " + convertLocation(micInfo.getLocation()));
+        sb.append("\nMinSPL     : " + micInfo.getMinSpl());
+        sb.append("\nMaxSPL     : " + micInfo.getMaxSpl());
+        sb.append("\nSensitivity: " + micInfo.getSensitivity());
+        sb.append("\nGroup      : " + micInfo.getGroup());
+        sb.append("\nIndexInTheGroup: " + micInfo.getIndexInTheGroup());
+        sb.append("\nOrientation: " + convertCoordinates(micInfo.getOrientation()));
+        sb.append("\nPosition   : " + convertCoordinates(micInfo.getPosition()));
+        sb.append("\nType       : " + micInfo.getType());
+
+        List<Pair<Integer, Integer>> mapping = micInfo.getChannelMapping();
+        sb.append("\nChannelMapping: {");
+        for (Pair<Integer, Integer> pair : mapping) {
+            sb.append("[" + pair.first + "," + pair.second + "], ");
+        }
+        sb.append("}");
+
+        sb.append("\n");
+        return sb.toString();
+    }
+
+}
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioOutputStream.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioOutputStream.java
index 52f9796..790fc4c 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioOutputStream.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioOutputStream.java
@@ -21,20 +21,12 @@
  */
 public class OboeAudioOutputStream extends OboeAudioStream {
 
-    // WARNING - must match order in strings.xml
-    public static final int TONE_TYPE_SAW_PING = 0;
-    public static final int TONE_TYPE_SINE = 1;
-    public static final int TONE_TYPE_IMPULSE = 2;
-    public static final int TONE_TYPE_SAWTOOTH = 3;
-
     @Override
     public boolean isInput() {
         return false;
     }
 
-    public native void setToneEnabled(boolean enabled);
-
-    public native void setToneType(int index);
+    public native void trigger();
 
     public native void setChannelEnabled(int channelIndex, boolean enabled);
 
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioStream.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioStream.java
index d13a85c..32462f1 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioStream.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/OboeAudioStream.java
@@ -204,7 +204,10 @@
     public native long getCallbackCount(); // TODO Move to another class?
 
     @Override
-    public native int getLastErrorCallbackResult(); // TODO Move to another class?
+    public int getLastErrorCallbackResult() {
+        return getLastErrorCallbackResult(streamIndex);
+    }
+    public native int getLastErrorCallbackResult(int streamIndex);
 
     @Override
     public long getFramesWritten() {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
index ee059e2..211987e 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
@@ -332,7 +332,7 @@
     }
 
     void startAutomaticTest() {
-        configureStreamsFromBundleForApi(mBundleFromIntent);
+        configureStreamsFromBundle(mBundleFromIntent);
         onMeasure(null);
         mBundleFromIntent = null;
     }
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TapToToneActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TapToToneActivity.java
index bc5b90a..b32ccfd 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TapToToneActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TapToToneActivity.java
@@ -90,13 +90,12 @@
                 switch (action) {
                     case MotionEvent.ACTION_DOWN:
                     case MotionEvent.ACTION_POINTER_DOWN:
-                        mAudioMidiTester.setEnabled(true);
+                        mAudioMidiTester.trigger();
                         break;
                     case MotionEvent.ACTION_MOVE:
                         break;
                     case MotionEvent.ACTION_UP:
                     case MotionEvent.ACTION_POINTER_UP:
-                        mAudioMidiTester.setEnabled(false);
                         break;
                 }
                 // Must return true or we do not get the ACTION_MOVE and
@@ -347,11 +346,6 @@
         resetLatency();
         try {
             mAudioMidiTester.start();
-            if (mAudioOutTester != null) {
-                mAudioOutTester.setToneType(OboeAudioOutputStream.TONE_TYPE_SAW_PING);
-            } else {
-                Log.w(TAG, "startAudioPermitted, mAudioOutTester = null, cannot setToneType(ping)");
-            }
         } catch (IOException e) {
             e.printStackTrace();
         }
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestDisconnectActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestDisconnectActivity.java
index aa94404..ce9a5f4 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestDisconnectActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestDisconnectActivity.java
@@ -262,13 +262,14 @@
         return ((config.getDirection() == StreamConfiguration.DIRECTION_OUTPUT) ? "OUT" : "IN")
                 + ", Perf = " + StreamConfiguration.convertPerformanceModeToText(
                 config.getPerformanceMode())
-                + ", " + StreamConfiguration.convertSharingModeToText(config.getSharingMode());
+                + ", " + StreamConfiguration.convertSharingModeToText(config.getSharingMode())
+                + ", " + config.getSampleRate();
     }
 
     private void testConfiguration(boolean isInput,
                                    int perfMode,
                                    int sharingMode,
-                                   int channelCount,
+                                   int sampleRate,
                                    boolean requestPlugin) throws InterruptedException {
         String actualConfigText = "none";
         mSkipTest = false;
@@ -295,7 +296,10 @@
         requestedConfig.reset();
         requestedConfig.setPerformanceMode(perfMode);
         requestedConfig.setSharingMode(sharingMode);
-        requestedConfig.setChannelCount(channelCount);
+        requestedConfig.setSampleRate(sampleRate);
+        if (sampleRate != 0) {
+            requestedConfig.setRateConversionQuality(StreamConfiguration.RATE_CONVERSION_QUALITY_MEDIUM);
+        }
 
         log("========================== #" + mTestCount);
         log("Requested:");
@@ -427,12 +431,17 @@
     }
 
     private void testConfiguration(boolean isInput, int performanceMode,
-                                   int sharingMode) throws InterruptedException {
-        int channelCount = 2;
+                                   int sharingMode, int sampleRate) throws InterruptedException {
         boolean requestPlugin = true; // plug IN
-        testConfiguration(isInput, performanceMode, sharingMode, channelCount, requestPlugin);
+        testConfiguration(isInput, performanceMode, sharingMode, sampleRate, requestPlugin);
         requestPlugin = false; // UNplug
-        testConfiguration(isInput, performanceMode, sharingMode, channelCount, requestPlugin);
+        testConfiguration(isInput, performanceMode, sharingMode, sampleRate, requestPlugin);
+    }
+
+    private void testConfiguration(boolean isInput, int performanceMode,
+                                   int sharingMode) throws InterruptedException {
+        final int sampleRate = 0;
+        testConfiguration(isInput, performanceMode, sharingMode, sampleRate);
     }
 
     private void testConfiguration(int performanceMode,
@@ -454,6 +463,8 @@
         mFailCount = 0;
         // Try several different configurations.
         try {
+            testConfiguration(false, StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY,
+                    StreamConfiguration.SHARING_MODE_EXCLUSIVE, 44100);
             testConfiguration(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY,
                         StreamConfiguration.SHARING_MODE_EXCLUSIVE);
             testConfiguration(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY,
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
index d7066ef..f57e454 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
@@ -17,7 +17,6 @@
 package com.google.sample.oboe.manualtest;
 
 import android.os.Bundle;
-import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.CheckBox;
@@ -71,7 +70,6 @@
         mChannelBoxes[ic++] = (CheckBox) findViewById(R.id.channelBox7);
         configureChannelBoxes(0);
 
-
         mNativeApiSpinner = (Spinner) findViewById(R.id.spinnerOutputSignal);
         mNativeApiSpinner.setOnItemSelectedListener(new NativeApiSpinnerListener());
         mNativeApiSpinner.setSelection(StreamConfiguration.NATIVE_API_UNSPECIFIED);
@@ -96,17 +94,6 @@
         }
     }
 
-    public void startAudio() {
-        super.startAudio();
-        mAudioOutTester.setToneType(OboeAudioOutputStream.TONE_TYPE_SINE);
-        mAudioOutTester.setEnabled(true);
-    }
-
-    public void stopAudio() {
-        mAudioOutTester.setEnabled(false);
-        super.stopAudio();
-    }
-
     public void closeAudio() {
         configureChannelBoxes(0);
         super.closeAudio();
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivityBase.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivityBase.java
index 9ea9164..8cfeb07 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivityBase.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivityBase.java
@@ -53,7 +53,6 @@
         return audioOutTester;
     }
 
-
     @Override
     public void openAudio() throws IOException {
         super.openAudio();
diff --git a/apps/OboeTester/app/src/main/res/layout/activity_device_report.xml b/apps/OboeTester/app/src/main/res/layout/activity_device_report.xml
new file mode 100644
index 0000000..e76bf69
--- /dev/null
+++ b/apps/OboeTester/app/src/main/res/layout/activity_device_report.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="com.google.sample.oboe.manualtest.DeviceReportActivity">
+
+    <TextView
+        android:id="@+id/text_log"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fontFamily="monospace"
+        android:gravity="bottom"
+        android:scrollbars="vertical"
+        android:text="@string/device_report" />
+
+</LinearLayout>
diff --git a/apps/OboeTester/app/src/main/res/layout/activity_main.xml b/apps/OboeTester/app/src/main/res/layout/activity_main.xml
index a78ddcd..5d0cce2 100644
--- a/apps/OboeTester/app/src/main/res/layout/activity_main.xml
+++ b/apps/OboeTester/app/src/main/res/layout/activity_main.xml
@@ -109,6 +109,16 @@
         android:layout_height="wrap_content"
         android:onClick="onLaunchTestDisconnect"
         android:text="Test Disconnect" />
+
+    <Button
+        android:id="@+id/button_test_device_report"
+        android:layout_gravity="fill"
+        android:layout_width="0dp"
+        android:layout_columnWeight="1"
+        android:layout_height="wrap_content"
+        android:onClick="onLaunchTestDeviceReport"
+        android:text="@string/title_report_devices" />
+
     </GridLayout>
 
     <CheckBox
diff --git a/apps/OboeTester/app/src/main/res/layout/audio_devices.xml b/apps/OboeTester/app/src/main/res/layout/audio_devices.xml
index 12ec7f6..143b9fd 100644
--- a/apps/OboeTester/app/src/main/res/layout/audio_devices.xml
+++ b/apps/OboeTester/app/src/main/res/layout/audio_devices.xml
@@ -14,9 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/device_name"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:text="Device Name"/>
+    android:fontFamily="sans-serif"
+    android:text="Device Name" />
diff --git a/apps/OboeTester/app/src/main/res/values/strings.xml b/apps/OboeTester/app/src/main/res/values/strings.xml
index 7d30606..45ded34 100644
--- a/apps/OboeTester/app/src/main/res/values/strings.xml
+++ b/apps/OboeTester/app/src/main/res/values/strings.xml
@@ -123,6 +123,8 @@
     <string name="title_activity_echo">Echo Input to Output</string>
     <string name="title_activity_rt_latency">Round Trip Latency</string>
     <string name="title_activity_glitches">Test Glitches</string>
+    <string name="title_test_disconnect">Test Disconnect</string>
+    <string name="title_report_devices">Report Devices</string>
 
     <string name="need_record_audio_permission">"This app needs RECORD_AUDIO permission"</string>
     <string name="share">Share</string>
@@ -130,13 +132,13 @@
     <string name="duration">Duration:</string>
     <string name="auto_glitch_instructions">Use loopback adapter or speakers.</string>
     <string name="log_of_glitch_tests">Log of Glitch Tests</string>
+    <string name="device_report">Device Report</string>
     <string name="save_file">Save</string>
 
     <string name="src_prompt">SRC:</string>
     <string name="average">Average</string>
     <string name="failTest">Fail</string>
     <string name="skipTest">Skip</string>
-    <string name="title_test_disconnect">Test Disconnect</string>
     <string name="test_disconnect_instructions">Unplug all headsets then click [START]</string>
     <string-array name="conversion_qualities">
         <item>None</item>
diff --git a/apps/OboeTester/docs/AutomatedTesting.md b/apps/OboeTester/docs/AutomatedTesting.md
index 85c8635..77a5096 100644
--- a/apps/OboeTester/docs/AutomatedTesting.md
+++ b/apps/OboeTester/docs/AutomatedTesting.md
@@ -54,28 +54,29 @@
     --ei buffer_bursts      {bursts}     // number of bursts in the buffer, 2 for "double buffered"
     --es in_api             {"unspecified", "opensles", "aaudio"}  // native input API, default is "unspecified"
     --es out_api            {"unspecified", "opensles", "aaudio"}  // native output API, default is "unspecified"
+    --ei in_channels        {samples}    // number of input channels, default is 2
+    --ei out_channels       {samples}    // number of output channels, default is 2
+    --ei sample_rate        {hertz}
+    --es in_perf            {"none", "lowlat", "powersave"}  // input performance mode, default is "lowlat"
+    --es out_perf           {"none", "lowlat", "powersave"}  // output performance mode, default is "lowlat"
+    --es in_sharing         {"shared", "exclusive"} // input sharing mode, default is "exclusive"
+    --es out_sharing        {"shared", "exclusive"} // output sharing mode, default is "exclusive"
     
 There are several optional parameters for just the "glitch" test:
 
-    --ei sample_rate        {hertz}
     --ef tolerance          {tolerance}  // amount of deviation from expected that is considered a glitch
                                          // Range of tolerance is 0.0 to 1.0. Default is 0.1. Note use of "-ef".
     --ei duration           {seconds}    // glitch test duration, default is 10 seconds
-    --ei in_channels        {samples}    // number of input channels, default is 2
-    --ei out_channels       {samples}    // number of output channels, default is 2
-    --es in_perf            {"none", "lowlat", "powersave"}  // input performance mode, default is "lowlat"
-    --es out_perf           {"none", "lowlat", "powersave"}  // output performance mode, default is "lowlat"
                             // input preset, default is "voicerec"
     --es in_preset          ("generic", "camcorder", "voicerec", "voicecomm", "unprocessed", "performance"}
-    --es in_sharing         {"shared", "exclusive"} // input sharing mode, default is "exclusive"
-    --es out_sharing        {"shared", "exclusive"} // output sharing mode, default is "exclusive"
 
-For example, a complete command might be:
+For example, a complete command for a "latency" test might be:
 
     adb shell am start -n com.google.sample.oboe.manualtest/.MainActivity \
         --es test latency \
         --es file /sdcard/latency20190903.txt \
-        --ei buffer_bursts 2
+        --ei buffer_bursts 2 \
+        --ei out_channels 1
         
 or for a "glitch" test:
 
@@ -90,7 +91,6 @@
         --ei sample_rate 48000 \
         --ef tolerance 0.123 \
         --ei in_channels 2 \
-        --ei out_channels 2 
 
 ## Interpreting Test Results
 
diff --git a/docs/AndroidAudioHistory.md b/docs/AndroidAudioHistory.md
index 6f8b0ad..95129ed 100644
--- a/docs/AndroidAudioHistory.md
+++ b/docs/AndroidAudioHistory.md
@@ -3,13 +3,19 @@
 

 A list of important audio features, bugs, fixes and workarounds for various Android versions. [(List of all Android Versions)](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

 

+### 11.0 R - API 30

+- Bug in **AAudio** on RQ1A (Oboe works around this issue from version 1.5 onwards). A stream is normally disconnected when a **headset is plugged in** or because of other device changes. An `AAUDIO_ERROR_DISCONNECTED` error code should be passed to the error callback. But a bug in Shared MMAP streams causes `AAUDIO_ERROR_TIMEOUT` to be returned. So if your error callback is checking for `AAUDIO_ERROR_DISCONNECTED` then it may not respond properly. We recommend **always stopping and closing the stream** regardless of the error code. Oboe does this. So if you are using Oboe callbacks you are OK. This issue was not in the original R release. It was introduced in RQ1A, which is being delivered by OTA starting in November 2020. It will be fixed in a future update. Follow it on [this public Android issue](https://issuetracker.google.com/173928197).

+

+- Fixed. A race condition in AudioFlinger could cause an assert in releaseBuffer() when a headset was plugged in or out. More details [here](notes/rlsbuffer.md)

+

 ### 10.0 Q - API 29

-- Fixed: Setting capacity of Legacy input streams < 4096 can prevent use of FAST path. https://github.com/google/oboe/issues/183. also ag/7116429

+- Fixed: Setting capacity of Legacy input streams < 4096 can prevent use of FAST path. https://github.com/google/oboe/issues/183. Also fixed in AAudio with ag/7116429

 - Add InputPreset:VoicePerformance for low latency recording.

+- Regression bug: [AAudio] Headphone disconnect event not fired for MMAP streams. See P item below. Still in first Q release but fixed in some Q updates. 

 

 ### 9.0 Pie - API 28 (August 6, 2018)

 - AAudio adds support for setUsage(), setSessionId(), setContentType(), setInputPreset() for builders.

-- Regression bug: [AAudio] Headphone disconnect event not fired for MMAP streams. https://github.com/google/oboe/issues/252

+- Regression bug: [AAudio] Headphone disconnect event not fired for MMAP streams. Issue [#252](https://github.com/google/oboe/issues/252) Also see tech note [Disconnected Streams](notes/disconnect.md).

 - AAudio input streams with LOW_LATENCY will open a FAST path using INT16 and convert the data to FLOAT if needed. See: https://github.com/google/oboe/issues/276

 

 ### 8.1 Oreo MR1 - API 27

@@ -41,4 +47,3 @@
 

 

 

-

diff --git a/docs/AppsUsingOboe.md b/docs/AppsUsingOboe.md
index 48a574a..a3e67f8 100644
--- a/docs/AppsUsingOboe.md
+++ b/docs/AppsUsingOboe.md
@@ -19,6 +19,7 @@
 | [ktnes](https://github.com/felipecsl/ktnes) | A NES emulator implemented in Kotlin using multiplatform support and Kotlin/Native. | Felipe Lima | | 
 | [Les Talens Lyriques apps](https://play.google.com/store/apps/developer?id=Les+Talens+Lyriques) | Music education apps | Les Talens Lyriques |  Stream opened with 44100 Hz so it will not get an MMAP stream on Pixel |
 | [libGDX Oboe](https://github.com/barsoosayque/libgdx-oboe) | Middleware | barsoosayque |  Libgdx audio replacement for Android built on top of Oboe. |
+| [Koala Sampler](https://play.google.com/store/apps/details?id=com.elf.koalasampler) | Koala is the ultimate pocket-sized sampler. Record anything with your phone's mic instantly. Use Koala to create beats with those samples, add effects and create a track! | elf audio |
 | [Mini Piano Lite](https://play.google.com/store/apps/details?id=umito.android.minipiano) | Piano keyboard | Umito | Using AAudio  |
 | [Mini Tunes](https://play.google.com/store/apps/details?id=com.minitunes) | Microtonal Synthesizer for Android | Fade Apps | Oboe implemented in version 2.0 | 
 | [Music Speed Changer](https://play.google.com/store/apps/details?id=com.smp.musicspeed) | Play song files while changing the pitch and tempo. | Single Minded Productions |  | 
diff --git a/docs/FAQ.md b/docs/FAQ.md
index a152646..00d86bb 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -9,7 +9,7 @@
 
 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))
 Also you can use blocking writes with the Java AudioTrack and still get a low latency stream.
-Oboe requires a callback to get a low latency stream and that does not work well with Java.
+Oboe requires a data callback to get a low latency stream and that does not work well with Java.
 
 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.
 
@@ -31,7 +31,7 @@
 ## I requested a stream with `PerformanceMode::LowLatency`, but didn't get it. Why not?
 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: 
 
-- You are opening an output stream and did not specify a **callback**.
+- You are opening an output stream and did not specify a **data callback**.
 - 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.
 - 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).
 - The audio **device** does not support `LowLatency` streams, for example Bluetooth. 
diff --git a/docs/FullGuide.md b/docs/FullGuide.md
index 1a4a682..931b67f 100644
--- a/docs/FullGuide.md
+++ b/docs/FullGuide.md
@@ -111,7 +111,6 @@
 are unspecified, a default value will still be set, and should be queried by the 
 appropriate accessor.
 
-* callback 
 * framesPerCallback
 * sampleRate
 * channelCount
@@ -149,7 +148,7 @@
 The actual size used may not be what was requested.
 Oboe or the underlyng API will limit the size between zero and the buffer capacity.
 It may also be limited further to reduce glitching on particular devices.
-This features is not supported when using OpenSL ES callbacks.
+This feature is not supported when using a callback with OpenSL ES.
 
 Many of the stream's properties may vary (whether or not you set
 them) depending on the capabilities of the audio device and the Android device on 
@@ -166,7 +165,8 @@
 
 | AudioStreamBuilder set methods | AudioStream get methods |
 | :------------------------ | :----------------- |
-| `setCallback()` |  `getCallback()` |
+| `setDataCallback()` |  `getDataCallback()` |
+| `setErrorCallback()` |  `getErrorCallback()` |
 | `setDirection()` | `getDirection()` |
 | `setSharingMode()` | `getSharingMode()` |
 | `setPerformanceMode()` | `getPerformanceMode()` |
@@ -222,7 +222,7 @@
 Note that you can only request pause or flush on an output stream:
 
 These functions are asynchronous, and the state change doesn't happen
-immediately. When you request a state change, the stream moves toone of the
+immediately. When you request a state change, the stream moves to one of the
 corresponding transient states:
 
 *   Starting
@@ -276,7 +276,7 @@
 
 There are two ways to move data in or out of a stream.
 1) Read from or write directly to the stream.
-2) Specify a callback object that will get called when the stream is ready.
+2) Specify a data callback object that will get called when the stream is ready.
 
 The callback technique offers the lowest latency performance because the callback code can run in a high priority thread.
 Also, attempting to open a low latency output stream without an audio callback (with the intent to use writes)
@@ -329,9 +329,8 @@
 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.
 
 If you need to be informed when an audio device is disconnected, write a class
-which extends `AudioStreamCallback` and then register your class using `builder.setCallback(yourCallbackClass)`.
+which extends `AudioStreamErrorCallback` and then register your class using `builder.setErrorCallback(yourCallbackClass)`.
 If you register a callback, then it will automatically close the stream in a separate thread if the stream is disconnected.
-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.
 
 Your callback can implement the following methods (called in a separate thread): 
 
@@ -343,7 +342,7 @@
 During this callback, stream properties (those requested by the builder) can be queried, as well as frames written and read.
 The stream can be deleted at the end of this method (as long as it not referenced in other threads).
 Methods that reference the underlying stream should not be called (e.g. `getTimestamp()`, `getXRunCount()`, `read()`, `write()`, etc.).
-Opening a seperate stream is also a valid use of this callback, especially if the error received is `Error::Disconnected`. 
+Opening a separate stream is also a valid use of this callback, especially if the error received is `Error::Disconnected`. 
 However, it is important to note that the new audio device may have vastly different properties than the stream that was disconnected.
 
 
@@ -351,7 +350,7 @@
 
 You can optimize the performance of an audio application by using special high-priority threads.
 
-### Using a high priority callback
+### Using a high priority data callback
 
 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.
 Using larger buffers might guard against such glitches, but a large buffer also introduces longer audio latency.
@@ -359,10 +358,10 @@
 The callback runs in a high-priority thread that has better performance.
 
 Your code can access the callback mechanism by implementing the virtual class
-`AudioStreamCallback`. The stream periodically executes `onAudioReady()` (the
+`AudioStreamDataCallback`. The stream periodically executes `onAudioReady()` (the
 callback function) to acquire the data for its next burst.
 
-    class AudioEngine : AudioStreamCallback {
+    class AudioEngine : AudioStreamDataCallback {
     public:
         DataCallbackResult AudioEngine::onAudioReady(
                 AudioStream *oboeStream,
@@ -375,7 +374,7 @@
         bool AudioEngine::start() {
             ...
             // register the callback
-            streamBuilder.setCallback(this);
+            streamBuilder.setDataCallback(this);
         }
     private:
         // application data
@@ -383,7 +382,7 @@
     }
 
 
-Note that the callback must be registered on the stream with `setCallback`. Any
+Note that the callback must be registered on the stream with `setDataCallback`. Any
 application-specific data (such as `oscillator_` in this case)
 can be included within the class itself.
 
@@ -394,10 +393,10 @@
 
 The callback does a non-blocking read from the input stream placing the data into the buffer of the output stream.
 
-    class AudioEngine : AudioStreamCallback {
+    class AudioEngine : AudioStreamDataCallback {
     public:
 
-        oboe_data_callback_result_t AudioEngine::onAudioReady(
+        DataCallbackResult AudioEngine::onAudioReady(
                 AudioStream *oboeStream,
                 void *audioData,
                 int32_t numFrames) {
@@ -419,7 +418,7 @@
 
         bool AudioEngine::start() {
             ...
-            streamBuilder.setCallback(this);
+            streamBuilder.setDataCallback(this);
         }
 
         void setRecordingStream(AudioStream *stream) {
@@ -433,7 +432,7 @@
 
 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.
 
-#### Callback do's and don'ts 
+#### Data Callback - Do's and Don'ts 
 You should never perform an operation which could block inside `onAudioReady`. Examples of blocking operations include:
 
 - allocate memory using, for example, malloc() or new
@@ -466,7 +465,7 @@
 If saving power is more important than low latency in your application, use `PerformanceMode::PowerSaving`.
 This is typical for apps that play back previously generated music, such as streaming audio or MIDI file players.
 
-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:
+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:
 
 ```
 // Create a callback object
@@ -474,7 +473,7 @@
 
 // Create a stream builder
 AudioStreamBuilder builder;
-builder.setCallback(myCallback);
+builder.setDataCallback(myCallback);
 builder.setPerformanceMode(PerformanceMode::LowLatency);
 
 // Use it to create the stream
@@ -497,8 +496,7 @@
 * `convertToText()`
 * `AudioStream::get*()` except for `getTimestamp()` and `getState()`
 
-<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
-from the thread in which it is running.
+<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.
 
 
 ## Code samples
diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md
index cfa27ce..2c32214 100644
--- a/docs/GettingStarted.md
+++ b/docs/GettingStarted.md
@@ -31,6 +31,19 @@
     find_package (oboe REQUIRED CONFIG)
     target_link_libraries(app oboe::oboe) # You may have other libraries here such as `log`.
 
+Here's a complete example `CMakeLists.txt` file:
+
+    cmake_minimum_required(VERSION 3.4.1)
+
+    # Build our own native library
+    add_library (native-lib SHARED native-lib.cpp )
+
+    # Find the Oboe package
+    find_package (oboe REQUIRED CONFIG)
+
+    # Specify the libraries which our native library is dependent on, including Oboe
+    target_link_libraries(app log oboe::oboe)
+
 Configure your app to use the shared STL by updating your `app/build.gradle`: 
 
     android { 
@@ -136,13 +149,13 @@
 oboe::AudioStreamBuilder builder;
 builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
   ->setSharingMode(oboe::SharingMode::Exclusive)
-  ->setCallback(myCallback)
+  ->setDataCallback(myCallback)
   ->setFormat(oboe::AudioFormat::Float);
 ```
 
-Define an `AudioStreamCallback` class to receive callbacks whenever the stream requires new data.
+Define an `AudioStreamDataCallback` class to receive callbacks whenever the stream requires new data.
 
-    class MyCallback : public oboe::AudioStreamCallback {
+    class MyCallback : public oboe::AudioStreamDataCallback {
     public:
         oboe::DataCallbackResult
         onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
@@ -170,7 +183,7 @@
 
 Supply this callback class to the builder:
 
-    builder.setCallback(&myCallback);
+    builder.setDataCallback(&myCallback);
     
 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.
 ```
@@ -190,7 +203,7 @@
 
 ## Playing audio
 Check the properties of the created stream. If you did not specify a channelCount, sampleRate, or format then you need to 
-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.
+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.
 
     oboe::AudioFormat format = stream->getFormat();
     LOGI("AudioStream format is %s", oboe::convertToText(format));
@@ -253,7 +266,7 @@
 #include <oboe/Oboe.h>
 #include <math.h>
 
-class OboeSinePlayer: public oboe::AudioStreamCallback {
+class OboeSinePlayer: public oboe::AudioStreamDataCallback {
 public:
 
 
@@ -265,7 +278,7 @@
           ->setChannelCount(kChannelCount)
           ->setSampleRate(kSampleRate)
           ->setFormat(oboe::AudioFormat::Float)
-          ->setCallback(this)
+          ->setDataCallback(this)
           ->openManagedStream(outStream);
         // Typically, start the stream after querying some stream information, as well as some input from the user
         outStream->requestStart();
@@ -301,8 +314,8 @@
 ```
 Note that this implementation computes  sine values at run-time for simplicity,
 rather than pre-computing them.
-Additionally, best practice is to implement a separate callback class, rather
-than managing the stream and defining its callback in the same class.
+Additionally, best practice is to implement a separate data callback class, rather
+than managing the stream and defining its data callback in the same class.
 This class also automatically starts the stream upon construction. Typically,
 the stream is queried for information prior to being started (e.g. burst size),
 and started upon user input.
diff --git a/docs/OpenSLESMigration.md b/docs/OpenSLESMigration.md
index 3792f96..ecdf588 100644
--- a/docs/OpenSLESMigration.md
+++ b/docs/OpenSLESMigration.md
@@ -26,7 +26,7 @@
 
 OpenSL uses audio player and audio recorder objects to communicate with audio devices. In Oboe an `AudioStream` is used.
 
-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.  
+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.  
 
 Here's a table which summarizes the object mappings:
 
@@ -59,7 +59,7 @@
   <tr>
    <td>Callback function
    </td>
-   <td><code>AudioStreamCallback::onAudioReady</code>
+   <td><code>AudioStreamDataCallback::onAudioReady</code>
    </td>
   </tr>
 </table>
@@ -84,7 +84,7 @@
 ```
 
 
-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)
+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)
 
 
 ### Buffer sizes
@@ -124,7 +124,7 @@
 
 OpenSL has no mechanism, other than stopping callbacks, to indicate that an audio device has been disconnected - for example, when headphones are unplugged.
 
-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)).
+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)).
 
 
 # Unsupported features
@@ -162,8 +162,8 @@
 
 *   Replace your audio player or recorder with an `AudioStream` created using an `AudioStreamBuilder`.
 *   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)`.
-*   Create an `AudioStreamCallback` object and move your OpenSL callback code inside the `onAudioReady` method.
-*   Handle stream disconnect events by overriding one of the `AudioStreamCallback::onError` methods.
+*   Create an `AudioStreamDataCallback` object and move your OpenSL callback code inside the `onAudioReady` method.
+*   Handle stream disconnect events by creating an `AudioStreamErrorCallback` object and overriding one of its `onError` methods.
 *   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.
 
 For more information please read the [Full Guide to Oboe](https://github.com/google/oboe/blob/master/docs/FullGuide.md).
diff --git a/docs/notes/disconnect.md b/docs/notes/disconnect.md
index 5b5abf2..08ee633 100644
--- a/docs/notes/disconnect.md
+++ b/docs/notes/disconnect.md
@@ -9,7 +9,7 @@
 the stream is no longer available and becomes "disconnected".
 The app should then be notified in one of two ways. 
 
-1) If the app is using a callback then the AudioStreamCallback object will be called.
+1) If the app is using an error callback then the AudioStreamErrorCallback methods will be called.
 It will launch a thread, which will call onErrorBeforeClose().
 Then it stops and closes the stream.
 Then onErrorAfterClose() will be called.
diff --git a/docs/reference/_audio_stream_8h_source.html b/docs/reference/_audio_stream_8h_source.html
index 965a0f1..e3d4e56 100644
--- a/docs/reference/_audio_stream_8h_source.html
+++ b/docs/reference/_audio_stream_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,42 +71,43 @@
 <div class="title">AudioStream.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &lt;ctime&gt;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#include &lt;mutex&gt;</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="preprocessor">#include &quot;oboe/ResultWithValue.h&quot;</span></div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBuilder.h&quot;</span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBase.h&quot;</span></div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00031"></a><span class="lineno"><a class="line" href="namespaceoboe.html">   31</a></span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno"><a class="line" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">   39</a></span>&#160;constexpr int64_t <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a> = (2000 * <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a>);</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;</div><div class="line"><a name="l00044"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html">   44</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>() {}</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> &amp;builder);</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;</div><div class="line"><a name="l00066"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">   66</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">open</a>() {</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;        <span class="keywordflow">return</span> Result::OK; <span class="comment">// Called by subclasses. Might do more in the future.</span></div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;    }</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>();</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">start</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a04f29836748a8e5842aef2be200022ad">pause</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a32c25c0333eab3d65ce02275ad4acb3d">flush</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#aec093859d42f0470c884edd1e976d9f3">stop</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;    <span class="comment">/* Asynchronous requests.</span></div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;<span class="comment">     * Use waitForStateChange() if you need to wait for completion.</span></div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a3c484e314dee8dfed1d419f487b5d601">requestStart</a>() = 0;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a7f18bb3cc5490fd7fbc1f6da63c730f6">requestPause</a>() = 0;</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a6bd5d633ff999e4da1faf3cd949aa602">requestFlush</a>() = 0;</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;</div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a820e634f741e6b5efdcef8104cecb919">requestStop</a>() = 0;</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> <a class="code" href="classoboe_1_1_audio_stream.html#a9d37cc6513823c685ae892626ff83ea8">getState</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;</div><div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a0c865a5501f369d959c39d8ab8b46a07">waitForStateChange</a>(<a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> inputState,</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;                                          <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> *nextState,</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;                                          int64_t timeoutNanoseconds) = 0;</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;</div><div class="line"><a name="l00177"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">  177</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">setBufferSizeInFrames</a>(int32_t <span class="comment">/* requestedFrames  */</span>) {</div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;        <span class="keywordflow">return</span> Result::ErrorUnimplemented;</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;    }</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;</div><div class="line"><a name="l00193"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">  193</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">getXRunCount</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;    }</div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;</div><div class="line"><a name="l00200"></a><span class="lineno">  200</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">isXRunCountSupported</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a">getFramesPerBurst</a>() = 0;</div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;</div><div class="line"><a name="l00216"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">  216</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">getBytesPerFrame</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> * <a class="code" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>(); }</div><div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;</div><div class="line"><a name="l00224"></a><span class="lineno">  224</span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00225"></a><span class="lineno">  225</span>&#160;</div><div class="line"><a name="l00232"></a><span class="lineno">  232</span>&#160;    <span class="keyword">virtual</span> int64_t <a class="code" href="classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341">getFramesWritten</a>();</div><div class="line"><a name="l00233"></a><span class="lineno">  233</span>&#160;</div><div class="line"><a name="l00240"></a><span class="lineno">  240</span>&#160;    <span class="keyword">virtual</span> int64_t <a class="code" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">getFramesRead</a>();</div><div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;</div><div class="line"><a name="l00265"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">  265</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;double&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">calculateLatencyMillis</a>() {</div><div class="line"><a name="l00266"></a><span class="lineno">  266</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;double&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;    }</div><div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;</div><div class="line"><a name="l00286"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">  286</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">getTimestamp</a>(clockid_t <span class="comment">/* clockId  */</span>,</div><div class="line"><a name="l00287"></a><span class="lineno">  287</span>&#160;                                int64_t* <span class="comment">/* framePosition */</span>,</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;                                int64_t* <span class="comment">/* timeNanoseconds */</span>) {</div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;        <span class="keywordflow">return</span> Result::ErrorUnimplemented;</div><div class="line"><a name="l00290"></a><span class="lineno">  290</span>&#160;    }</div><div class="line"><a name="l00291"></a><span class="lineno">  291</span>&#160;</div><div class="line"><a name="l00307"></a><span class="lineno">  307</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;FrameTimestamp&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">getTimestamp</a>(clockid_t <span class="comment">/* clockId */</span>);</div><div class="line"><a name="l00308"></a><span class="lineno">  308</span>&#160;</div><div class="line"><a name="l00309"></a><span class="lineno">  309</span>&#160;    <span class="comment">// ============== I/O ===========================</span></div><div class="line"><a name="l00322"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">  322</a></span>&#160;<span class="comment"></span>    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">write</a>(<span class="keyword">const</span> <span class="keywordtype">void</span>* <span class="comment">/* buffer */</span>,</div><div class="line"><a name="l00323"></a><span class="lineno">  323</span>&#160;                             int32_t <span class="comment">/* numFrames */</span>,</div><div class="line"><a name="l00324"></a><span class="lineno">  324</span>&#160;                             int64_t <span class="comment">/* timeoutNanoseconds */</span> ) {</div><div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;    }</div><div class="line"><a name="l00327"></a><span class="lineno">  327</span>&#160;</div><div class="line"><a name="l00340"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">  340</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">read</a>(<span class="keywordtype">void</span>* <span class="comment">/* buffer */</span>,</div><div class="line"><a name="l00341"></a><span class="lineno">  341</span>&#160;                            int32_t <span class="comment">/* numFrames */</span>,</div><div class="line"><a name="l00342"></a><span class="lineno">  342</span>&#160;                            int64_t <span class="comment">/* timeoutNanoseconds */</span>) {</div><div class="line"><a name="l00343"></a><span class="lineno">  343</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00344"></a><span class="lineno">  344</span>&#160;    }</div><div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;</div><div class="line"><a name="l00351"></a><span class="lineno">  351</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> <a class="code" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00352"></a><span class="lineno">  352</span>&#160;</div><div class="line"><a name="l00358"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">  358</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">usesAAudio</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00359"></a><span class="lineno">  359</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() == <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AudioApi::AAudio</a>;</div><div class="line"><a name="l00360"></a><span class="lineno">  360</span>&#160;    }</div><div class="line"><a name="l00361"></a><span class="lineno">  361</span>&#160;</div><div class="line"><a name="l00370"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">  370</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> *<a class="code" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">getUnderlyingStream</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00371"></a><span class="lineno">  371</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00372"></a><span class="lineno">  372</span>&#160;    }</div><div class="line"><a name="l00373"></a><span class="lineno">  373</span>&#160;</div><div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#aa5f4801cca6877eeaa4735b93933269d">launchStopThread</a>();</div><div class="line"><a name="l00378"></a><span class="lineno">  378</span>&#160;</div><div class="line"><a name="l00383"></a><span class="lineno">  383</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a64ad978c5f70ced17ef5a96605496515">updateFramesWritten</a>() = 0;</div><div class="line"><a name="l00384"></a><span class="lineno">  384</span>&#160;</div><div class="line"><a name="l00389"></a><span class="lineno">  389</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">updateFramesRead</a>() = 0;</div><div class="line"><a name="l00390"></a><span class="lineno">  390</span>&#160;</div><div class="line"><a name="l00391"></a><span class="lineno">  391</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;<span class="comment">     * Swap old callback for new callback.</span></div><div class="line"><a name="l00393"></a><span class="lineno">  393</span>&#160;<span class="comment">     * This not atomic.</span></div><div class="line"><a name="l00394"></a><span class="lineno">  394</span>&#160;<span class="comment">     * This should only be used internally.</span></div><div class="line"><a name="l00395"></a><span class="lineno">  395</span>&#160;<span class="comment">     * @param streamCallback</span></div><div class="line"><a name="l00396"></a><span class="lineno">  396</span>&#160;<span class="comment">     * @return previous streamCallback</span></div><div class="line"><a name="l00397"></a><span class="lineno">  397</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00398"></a><span class="lineno">  398</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *swapCallback(<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *streamCallback) {</div><div class="line"><a name="l00399"></a><span class="lineno">  399</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *previousCallback = <a class="code" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a>;</div><div class="line"><a name="l00400"></a><span class="lineno">  400</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = streamCallback;</div><div class="line"><a name="l00401"></a><span class="lineno">  401</span>&#160;        <span class="keywordflow">return</span> previousCallback;</div><div class="line"><a name="l00402"></a><span class="lineno">  402</span>&#160;    }</div><div class="line"><a name="l00403"></a><span class="lineno">  403</span>&#160;</div><div class="line"><a name="l00407"></a><span class="lineno">  407</span>&#160;    ResultWithValue&lt;int32_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">getAvailableFrames</a>();</div><div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;</div><div class="line"><a name="l00418"></a><span class="lineno">  418</span>&#160;    ResultWithValue&lt;int32_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">waitForAvailableFrames</a>(int32_t numFrames,</div><div class="line"><a name="l00419"></a><span class="lineno">  419</span>&#160;                                                    int64_t timeoutNanoseconds);</div><div class="line"><a name="l00420"></a><span class="lineno">  420</span>&#160;</div><div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;<span class="keyword">protected</span>:</div><div class="line"><a name="l00422"></a><span class="lineno">  422</span>&#160;</div><div class="line"><a name="l00432"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">  432</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">wasErrorCallbackCalled</a>() {</div><div class="line"><a name="l00433"></a><span class="lineno">  433</span>&#160;        <span class="keywordflow">return</span> mErrorCallbackCalled.exchange(<span class="keyword">true</span>);</div><div class="line"><a name="l00434"></a><span class="lineno">  434</span>&#160;    }</div><div class="line"><a name="l00435"></a><span class="lineno">  435</span>&#160;</div><div class="line"><a name="l00442"></a><span class="lineno">  442</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a8adbacd6a55a94a532916ab037fba1d6">waitForStateTransition</a>(<a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> startingState,</div><div class="line"><a name="l00443"></a><span class="lineno">  443</span>&#160;                                          <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> endingState,</div><div class="line"><a name="l00444"></a><span class="lineno">  444</span>&#160;                                          int64_t timeoutNanoseconds);</div><div class="line"><a name="l00445"></a><span class="lineno">  445</span>&#160;</div><div class="line"><a name="l00453"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">  453</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">onDefaultCallback</a>(<span class="keywordtype">void</span>* <span class="comment">/* audioData  */</span>, <span class="keywordtype">int</span> <span class="comment">/* numFrames */</span>) {</div><div class="line"><a name="l00454"></a><span class="lineno">  454</span>&#160;        <span class="keywordflow">return</span> DataCallbackResult::Stop;</div><div class="line"><a name="l00455"></a><span class="lineno">  455</span>&#160;    }</div><div class="line"><a name="l00456"></a><span class="lineno">  456</span>&#160;</div><div class="line"><a name="l00465"></a><span class="lineno">  465</span>&#160;    <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream.html#ab7a8cfe5d6039386bc5850fd5ee9bd62">fireDataCallback</a>(<span class="keywordtype">void</span> *audioData, <span class="keywordtype">int</span> numFrames);</div><div class="line"><a name="l00466"></a><span class="lineno">  466</span>&#160;</div><div class="line"><a name="l00470"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">  470</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">isDataCallbackEnabled</a>() {</div><div class="line"><a name="l00471"></a><span class="lineno">  471</span>&#160;        <span class="keywordflow">return</span> mDataCallbackEnabled;</div><div class="line"><a name="l00472"></a><span class="lineno">  472</span>&#160;    }</div><div class="line"><a name="l00473"></a><span class="lineno">  473</span>&#160;</div><div class="line"><a name="l00478"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">  478</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">setDataCallbackEnabled</a>(<span class="keywordtype">bool</span> enabled) {</div><div class="line"><a name="l00479"></a><span class="lineno">  479</span>&#160;        mDataCallbackEnabled = enabled;</div><div class="line"><a name="l00480"></a><span class="lineno">  480</span>&#160;    }</div><div class="line"><a name="l00481"></a><span class="lineno">  481</span>&#160;</div><div class="line"><a name="l00488"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">  488</a></span>&#160;    std::atomic&lt;int64_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">mFramesWritten</a>{};</div><div class="line"><a name="l00489"></a><span class="lineno">  489</span>&#160;</div><div class="line"><a name="l00496"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">  496</a></span>&#160;    std::atomic&lt;int64_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">mFramesRead</a>{};</div><div class="line"><a name="l00497"></a><span class="lineno">  497</span>&#160;</div><div class="line"><a name="l00498"></a><span class="lineno">  498</span>&#160;    std::mutex           mLock; <span class="comment">// for synchronizing start/stop/close</span></div><div class="line"><a name="l00499"></a><span class="lineno">  499</span>&#160;</div><div class="line"><a name="l00500"></a><span class="lineno">  500</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00501"></a><span class="lineno">  501</span>&#160;    <span class="keywordtype">int</span>                  mPreviousScheduler = -1;</div><div class="line"><a name="l00502"></a><span class="lineno">  502</span>&#160;</div><div class="line"><a name="l00503"></a><span class="lineno">  503</span>&#160;    std::atomic&lt;bool&gt;    mDataCallbackEnabled{<span class="keyword">false</span>};</div><div class="line"><a name="l00504"></a><span class="lineno">  504</span>&#160;    std::atomic&lt;bool&gt;    mErrorCallbackCalled{<span class="keyword">false</span>};</div><div class="line"><a name="l00505"></a><span class="lineno">  505</span>&#160;</div><div class="line"><a name="l00506"></a><span class="lineno">  506</span>&#160;</div><div class="line"><a name="l00507"></a><span class="lineno">  507</span>&#160;};</div><div class="line"><a name="l00508"></a><span class="lineno">  508</span>&#160;</div><div class="line"><a name="l00513"></a><span class="lineno"><a class="line" href="structoboe_1_1_stream_deleter_functor.html">  513</a></span>&#160;    <span class="keyword">struct </span><a class="code" href="structoboe_1_1_stream_deleter_functor.html">StreamDeleterFunctor</a> {</div><div class="line"><a name="l00514"></a><span class="lineno">  514</span>&#160;        <span class="keywordtype">void</span> operator()(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>  *audioStream) {</div><div class="line"><a name="l00515"></a><span class="lineno">  515</span>&#160;            <span class="keywordflow">if</span> (audioStream) {</div><div class="line"><a name="l00516"></a><span class="lineno">  516</span>&#160;                audioStream-&gt;<a class="code" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>();</div><div class="line"><a name="l00517"></a><span class="lineno">  517</span>&#160;            }</div><div class="line"><a name="l00518"></a><span class="lineno">  518</span>&#160;            <span class="keyword">delete</span> audioStream;</div><div class="line"><a name="l00519"></a><span class="lineno">  519</span>&#160;        }</div><div class="line"><a name="l00520"></a><span class="lineno">  520</span>&#160;    };</div><div class="line"><a name="l00521"></a><span class="lineno">  521</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00522"></a><span class="lineno">  522</span>&#160;</div><div class="line"><a name="l00523"></a><span class="lineno">  523</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_html_a0ea79e60f5a3d29fc5a1a116aba11dfe"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">oboe::AudioStream::onDefaultCallback</a></div><div class="ttdeci">virtual DataCallbackResult onDefaultCallback(void *, int)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:453</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &lt;ctime&gt;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#include &lt;mutex&gt;</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="preprocessor">#include &quot;oboe/ResultWithValue.h&quot;</span></div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBuilder.h&quot;</span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBase.h&quot;</span></div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00031"></a><span class="lineno"><a class="line" href="namespaceoboe.html">   31</a></span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno"><a class="line" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">   39</a></span>&#160;constexpr int64_t <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a> = (2000 * <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a>);</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;</div><div class="line"><a name="l00044"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html">   44</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;    <span class="keyword">friend</span> <span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>; <span class="comment">// allow access to setWeakThis() and lockWeakThis()</span></div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>() {}</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> &amp;builder);</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;</div><div class="line"><a name="l00067"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">   67</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">open</a>() {</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;        <span class="keywordflow">return</span> Result::OK; <span class="comment">// Called by subclasses. Might do more in the future.</span></div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;    }</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>();</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">start</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a04f29836748a8e5842aef2be200022ad">pause</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a32c25c0333eab3d65ce02275ad4acb3d">flush</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#aec093859d42f0470c884edd1e976d9f3">stop</a>(int64_t timeoutNanoseconds = <a class="code" href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">kDefaultTimeoutNanos</a>);</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;    <span class="comment">/* Asynchronous requests.</span></div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;<span class="comment">     * Use waitForStateChange() if you need to wait for completion.</span></div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a3c484e314dee8dfed1d419f487b5d601">requestStart</a>() = 0;</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a7f18bb3cc5490fd7fbc1f6da63c730f6">requestPause</a>() = 0;</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a6bd5d633ff999e4da1faf3cd949aa602">requestFlush</a>() = 0;</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a820e634f741e6b5efdcef8104cecb919">requestStop</a>() = 0;</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> <a class="code" href="classoboe_1_1_audio_stream.html#a9d37cc6513823c685ae892626ff83ea8">getState</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a0c865a5501f369d959c39d8ab8b46a07">waitForStateChange</a>(<a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> inputState,</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;                                          <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> *nextState,</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;                                          int64_t timeoutNanoseconds) = 0;</div><div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;</div><div class="line"><a name="l00178"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">  178</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">setBufferSizeInFrames</a>(int32_t <span class="comment">/* requestedFrames  */</span>) {</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;        <span class="keywordflow">return</span> Result::ErrorUnimplemented;</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;    }</div><div class="line"><a name="l00181"></a><span class="lineno">  181</span>&#160;</div><div class="line"><a name="l00194"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">  194</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">getXRunCount</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;    }</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;</div><div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">isXRunCountSupported</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;</div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a">getFramesPerBurst</a>() = 0;</div><div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;</div><div class="line"><a name="l00217"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">  217</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">getBytesPerFrame</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> * <a class="code" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>(); }</div><div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;</div><div class="line"><a name="l00225"></a><span class="lineno">  225</span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00226"></a><span class="lineno">  226</span>&#160;</div><div class="line"><a name="l00233"></a><span class="lineno">  233</span>&#160;    <span class="keyword">virtual</span> int64_t <a class="code" href="classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341">getFramesWritten</a>();</div><div class="line"><a name="l00234"></a><span class="lineno">  234</span>&#160;</div><div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;    <span class="keyword">virtual</span> int64_t <a class="code" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">getFramesRead</a>();</div><div class="line"><a name="l00242"></a><span class="lineno">  242</span>&#160;</div><div class="line"><a name="l00266"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">  266</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;double&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">calculateLatencyMillis</a>() {</div><div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;double&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;    }</div><div class="line"><a name="l00269"></a><span class="lineno">  269</span>&#160;</div><div class="line"><a name="l00287"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">  287</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">getTimestamp</a>(clockid_t <span class="comment">/* clockId  */</span>,</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;                                int64_t* <span class="comment">/* framePosition */</span>,</div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;                                int64_t* <span class="comment">/* timeNanoseconds */</span>) {</div><div class="line"><a name="l00290"></a><span class="lineno">  290</span>&#160;        <span class="keywordflow">return</span> Result::ErrorUnimplemented;</div><div class="line"><a name="l00291"></a><span class="lineno">  291</span>&#160;    }</div><div class="line"><a name="l00292"></a><span class="lineno">  292</span>&#160;</div><div class="line"><a name="l00308"></a><span class="lineno">  308</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;FrameTimestamp&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">getTimestamp</a>(clockid_t <span class="comment">/* clockId */</span>);</div><div class="line"><a name="l00309"></a><span class="lineno">  309</span>&#160;</div><div class="line"><a name="l00310"></a><span class="lineno">  310</span>&#160;    <span class="comment">// ============== I/O ===========================</span></div><div class="line"><a name="l00323"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">  323</a></span>&#160;<span class="comment"></span>    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">write</a>(<span class="keyword">const</span> <span class="keywordtype">void</span>* <span class="comment">/* buffer */</span>,</div><div class="line"><a name="l00324"></a><span class="lineno">  324</span>&#160;                             int32_t <span class="comment">/* numFrames */</span>,</div><div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;                             int64_t <span class="comment">/* timeoutNanoseconds */</span> ) {</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00327"></a><span class="lineno">  327</span>&#160;    }</div><div class="line"><a name="l00328"></a><span class="lineno">  328</span>&#160;</div><div class="line"><a name="l00341"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">  341</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a> <a class="code" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">read</a>(<span class="keywordtype">void</span>* <span class="comment">/* buffer */</span>,</div><div class="line"><a name="l00342"></a><span class="lineno">  342</span>&#160;                            int32_t <span class="comment">/* numFrames */</span>,</div><div class="line"><a name="l00343"></a><span class="lineno">  343</span>&#160;                            int64_t <span class="comment">/* timeoutNanoseconds */</span>) {</div><div class="line"><a name="l00344"></a><span class="lineno">  344</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_result_with_value.html">ResultWithValue&lt;int32_t&gt;</a>(Result::ErrorUnimplemented);</div><div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;    }</div><div class="line"><a name="l00346"></a><span class="lineno">  346</span>&#160;</div><div class="line"><a name="l00352"></a><span class="lineno">  352</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> <a class="code" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() <span class="keyword">const</span> = 0;</div><div class="line"><a name="l00353"></a><span class="lineno">  353</span>&#160;</div><div class="line"><a name="l00359"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">  359</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">usesAAudio</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00360"></a><span class="lineno">  360</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() == <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AudioApi::AAudio</a>;</div><div class="line"><a name="l00361"></a><span class="lineno">  361</span>&#160;    }</div><div class="line"><a name="l00362"></a><span class="lineno">  362</span>&#160;</div><div class="line"><a name="l00371"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">  371</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> *<a class="code" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">getUnderlyingStream</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00372"></a><span class="lineno">  372</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00373"></a><span class="lineno">  373</span>&#160;    }</div><div class="line"><a name="l00374"></a><span class="lineno">  374</span>&#160;</div><div class="line"><a name="l00378"></a><span class="lineno">  378</span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#aa5f4801cca6877eeaa4735b93933269d">launchStopThread</a>();</div><div class="line"><a name="l00379"></a><span class="lineno">  379</span>&#160;</div><div class="line"><a name="l00384"></a><span class="lineno">  384</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a64ad978c5f70ced17ef5a96605496515">updateFramesWritten</a>() = 0;</div><div class="line"><a name="l00385"></a><span class="lineno">  385</span>&#160;</div><div class="line"><a name="l00390"></a><span class="lineno">  390</span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">updateFramesRead</a>() = 0;</div><div class="line"><a name="l00391"></a><span class="lineno">  391</span>&#160;</div><div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l00393"></a><span class="lineno">  393</span>&#160;<span class="comment">     * Swap old callback for new callback.</span></div><div class="line"><a name="l00394"></a><span class="lineno">  394</span>&#160;<span class="comment">     * This not atomic.</span></div><div class="line"><a name="l00395"></a><span class="lineno">  395</span>&#160;<span class="comment">     * This should only be used internally.</span></div><div class="line"><a name="l00396"></a><span class="lineno">  396</span>&#160;<span class="comment">     * @param dataCallback</span></div><div class="line"><a name="l00397"></a><span class="lineno">  397</span>&#160;<span class="comment">     * @return previous dataCallback</span></div><div class="line"><a name="l00398"></a><span class="lineno">  398</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00399"></a><span class="lineno">  399</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *swapDataCallback(<a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *dataCallback) {</div><div class="line"><a name="l00400"></a><span class="lineno">  400</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *previousCallback = <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a>;</div><div class="line"><a name="l00401"></a><span class="lineno">  401</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = dataCallback;</div><div class="line"><a name="l00402"></a><span class="lineno">  402</span>&#160;        <span class="keywordflow">return</span> previousCallback;</div><div class="line"><a name="l00403"></a><span class="lineno">  403</span>&#160;    }</div><div class="line"><a name="l00404"></a><span class="lineno">  404</span>&#160;</div><div class="line"><a name="l00405"></a><span class="lineno">  405</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l00406"></a><span class="lineno">  406</span>&#160;<span class="comment">     * Swap old callback for new callback.</span></div><div class="line"><a name="l00407"></a><span class="lineno">  407</span>&#160;<span class="comment">     * This not atomic.</span></div><div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;<span class="comment">     * This should only be used internally.</span></div><div class="line"><a name="l00409"></a><span class="lineno">  409</span>&#160;<span class="comment">     * @param errorCallback</span></div><div class="line"><a name="l00410"></a><span class="lineno">  410</span>&#160;<span class="comment">     * @return previous errorCallback</span></div><div class="line"><a name="l00411"></a><span class="lineno">  411</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00412"></a><span class="lineno">  412</span>&#160;    AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) {</div><div class="line"><a name="l00413"></a><span class="lineno">  413</span>&#160;        AudioStreamErrorCallback *previousCallback = <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a>;</div><div class="line"><a name="l00414"></a><span class="lineno">  414</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = errorCallback;</div><div class="line"><a name="l00415"></a><span class="lineno">  415</span>&#160;        <span class="keywordflow">return</span> previousCallback;</div><div class="line"><a name="l00416"></a><span class="lineno">  416</span>&#160;    }</div><div class="line"><a name="l00417"></a><span class="lineno">  417</span>&#160;</div><div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;    ResultWithValue&lt;int32_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">getAvailableFrames</a>();</div><div class="line"><a name="l00422"></a><span class="lineno">  422</span>&#160;</div><div class="line"><a name="l00432"></a><span class="lineno">  432</span>&#160;    ResultWithValue&lt;int32_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">waitForAvailableFrames</a>(int32_t numFrames,</div><div class="line"><a name="l00433"></a><span class="lineno">  433</span>&#160;                                                    int64_t timeoutNanoseconds);</div><div class="line"><a name="l00434"></a><span class="lineno">  434</span>&#160;</div><div class="line"><a name="l00438"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">  438</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">getLastErrorCallbackResult</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00439"></a><span class="lineno">  439</span>&#160;        <span class="keywordflow">return</span> mErrorCallbackResult;</div><div class="line"><a name="l00440"></a><span class="lineno">  440</span>&#160;    }</div><div class="line"><a name="l00441"></a><span class="lineno">  441</span>&#160;</div><div class="line"><a name="l00442"></a><span class="lineno">  442</span>&#160;<span class="keyword">protected</span>:</div><div class="line"><a name="l00443"></a><span class="lineno">  443</span>&#160;</div><div class="line"><a name="l00453"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">  453</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">wasErrorCallbackCalled</a>() {</div><div class="line"><a name="l00454"></a><span class="lineno">  454</span>&#160;        <span class="keywordflow">return</span> mErrorCallbackCalled.exchange(<span class="keyword">true</span>);</div><div class="line"><a name="l00455"></a><span class="lineno">  455</span>&#160;    }</div><div class="line"><a name="l00456"></a><span class="lineno">  456</span>&#160;</div><div class="line"><a name="l00463"></a><span class="lineno">  463</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream.html#a8adbacd6a55a94a532916ab037fba1d6">waitForStateTransition</a>(<a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> startingState,</div><div class="line"><a name="l00464"></a><span class="lineno">  464</span>&#160;                                          <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> endingState,</div><div class="line"><a name="l00465"></a><span class="lineno">  465</span>&#160;                                          int64_t timeoutNanoseconds);</div><div class="line"><a name="l00466"></a><span class="lineno">  466</span>&#160;</div><div class="line"><a name="l00474"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">  474</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">onDefaultCallback</a>(<span class="keywordtype">void</span>* <span class="comment">/* audioData  */</span>, <span class="keywordtype">int</span> <span class="comment">/* numFrames */</span>) {</div><div class="line"><a name="l00475"></a><span class="lineno">  475</span>&#160;        <span class="keywordflow">return</span> DataCallbackResult::Stop;</div><div class="line"><a name="l00476"></a><span class="lineno">  476</span>&#160;    }</div><div class="line"><a name="l00477"></a><span class="lineno">  477</span>&#160;</div><div class="line"><a name="l00486"></a><span class="lineno">  486</span>&#160;    <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream.html#ab7a8cfe5d6039386bc5850fd5ee9bd62">fireDataCallback</a>(<span class="keywordtype">void</span> *audioData, <span class="keywordtype">int</span> numFrames);</div><div class="line"><a name="l00487"></a><span class="lineno">  487</span>&#160;</div><div class="line"><a name="l00491"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">  491</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">isDataCallbackEnabled</a>() {</div><div class="line"><a name="l00492"></a><span class="lineno">  492</span>&#160;        <span class="keywordflow">return</span> mDataCallbackEnabled;</div><div class="line"><a name="l00493"></a><span class="lineno">  493</span>&#160;    }</div><div class="line"><a name="l00494"></a><span class="lineno">  494</span>&#160;</div><div class="line"><a name="l00499"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">  499</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">setDataCallbackEnabled</a>(<span class="keywordtype">bool</span> enabled) {</div><div class="line"><a name="l00500"></a><span class="lineno">  500</span>&#160;        mDataCallbackEnabled = enabled;</div><div class="line"><a name="l00501"></a><span class="lineno">  501</span>&#160;    }</div><div class="line"><a name="l00502"></a><span class="lineno">  502</span>&#160;</div><div class="line"><a name="l00503"></a><span class="lineno">  503</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l00504"></a><span class="lineno">  504</span>&#160;<span class="comment">     * Set a weak_ptr to this stream from the shared_ptr so that we can</span></div><div class="line"><a name="l00505"></a><span class="lineno">  505</span>&#160;<span class="comment">     * later use a shared_ptr in the error callback.</span></div><div class="line"><a name="l00506"></a><span class="lineno">  506</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00507"></a><span class="lineno">  507</span>&#160;    <span class="keywordtype">void</span> setWeakThis(std::shared_ptr&lt;oboe::AudioStream&gt; &amp;sharedStream) {</div><div class="line"><a name="l00508"></a><span class="lineno">  508</span>&#160;        mWeakThis = sharedStream;</div><div class="line"><a name="l00509"></a><span class="lineno">  509</span>&#160;    }</div><div class="line"><a name="l00510"></a><span class="lineno">  510</span>&#160;</div><div class="line"><a name="l00511"></a><span class="lineno">  511</span>&#160;    <span class="comment">/*</span></div><div class="line"><a name="l00512"></a><span class="lineno">  512</span>&#160;<span class="comment">     * Make a shared_ptr that will prevent this stream from being deleted.</span></div><div class="line"><a name="l00513"></a><span class="lineno">  513</span>&#160;<span class="comment">     */</span></div><div class="line"><a name="l00514"></a><span class="lineno">  514</span>&#160;    std::shared_ptr&lt;oboe::AudioStream&gt; lockWeakThis() {</div><div class="line"><a name="l00515"></a><span class="lineno">  515</span>&#160;        <span class="keywordflow">return</span> mWeakThis.lock();</div><div class="line"><a name="l00516"></a><span class="lineno">  516</span>&#160;    }</div><div class="line"><a name="l00517"></a><span class="lineno">  517</span>&#160;</div><div class="line"><a name="l00518"></a><span class="lineno">  518</span>&#160;    std::weak_ptr&lt;AudioStream&gt; mWeakThis; <span class="comment">// weak pointer to this object</span></div><div class="line"><a name="l00519"></a><span class="lineno">  519</span>&#160;</div><div class="line"><a name="l00526"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">  526</a></span>&#160;    std::atomic&lt;int64_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">mFramesWritten</a>{};</div><div class="line"><a name="l00527"></a><span class="lineno">  527</span>&#160;</div><div class="line"><a name="l00534"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">  534</a></span>&#160;    std::atomic&lt;int64_t&gt; <a class="code" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">mFramesRead</a>{};</div><div class="line"><a name="l00535"></a><span class="lineno">  535</span>&#160;</div><div class="line"><a name="l00536"></a><span class="lineno">  536</span>&#160;    std::mutex           mLock; <span class="comment">// for synchronizing start/stop/close</span></div><div class="line"><a name="l00537"></a><span class="lineno">  537</span>&#160;</div><div class="line"><a name="l00538"></a><span class="lineno">  538</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a>         mErrorCallbackResult = oboe::Result::OK;</div><div class="line"><a name="l00539"></a><span class="lineno">  539</span>&#160;</div><div class="line"><a name="l00540"></a><span class="lineno">  540</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00541"></a><span class="lineno">  541</span>&#160;</div><div class="line"><a name="l00542"></a><span class="lineno">  542</span>&#160;    <span class="comment">// Log the scheduler if it changes.</span></div><div class="line"><a name="l00543"></a><span class="lineno">  543</span>&#160;    <span class="keywordtype">void</span>                 checkScheduler();</div><div class="line"><a name="l00544"></a><span class="lineno">  544</span>&#160;    <span class="keywordtype">int</span>                  mPreviousScheduler = -1;</div><div class="line"><a name="l00545"></a><span class="lineno">  545</span>&#160;</div><div class="line"><a name="l00546"></a><span class="lineno">  546</span>&#160;    std::atomic&lt;bool&gt;    mDataCallbackEnabled{<span class="keyword">false</span>};</div><div class="line"><a name="l00547"></a><span class="lineno">  547</span>&#160;    std::atomic&lt;bool&gt;    mErrorCallbackCalled{<span class="keyword">false</span>};</div><div class="line"><a name="l00548"></a><span class="lineno">  548</span>&#160;</div><div class="line"><a name="l00549"></a><span class="lineno">  549</span>&#160;};</div><div class="line"><a name="l00550"></a><span class="lineno">  550</span>&#160;</div><div class="line"><a name="l00555"></a><span class="lineno"><a class="line" href="structoboe_1_1_stream_deleter_functor.html">  555</a></span>&#160;    <span class="keyword">struct </span><a class="code" href="structoboe_1_1_stream_deleter_functor.html">StreamDeleterFunctor</a> {</div><div class="line"><a name="l00556"></a><span class="lineno">  556</span>&#160;        <span class="keywordtype">void</span> operator()(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>  *audioStream) {</div><div class="line"><a name="l00557"></a><span class="lineno">  557</span>&#160;            <span class="keywordflow">if</span> (audioStream) {</div><div class="line"><a name="l00558"></a><span class="lineno">  558</span>&#160;                audioStream-&gt;<a class="code" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>();</div><div class="line"><a name="l00559"></a><span class="lineno">  559</span>&#160;            }</div><div class="line"><a name="l00560"></a><span class="lineno">  560</span>&#160;            <span class="keyword">delete</span> audioStream;</div><div class="line"><a name="l00561"></a><span class="lineno">  561</span>&#160;        }</div><div class="line"><a name="l00562"></a><span class="lineno">  562</span>&#160;    };</div><div class="line"><a name="l00563"></a><span class="lineno">  563</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00564"></a><span class="lineno">  564</span>&#160;</div><div class="line"><a name="l00565"></a><span class="lineno">  565</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_html_a0ea79e60f5a3d29fc5a1a116aba11dfe"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">oboe::AudioStream::onDefaultCallback</a></div><div class="ttdeci">virtual DataCallbackResult onDefaultCallback(void *, int)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:474</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_aec093859d42f0470c884edd1e976d9f3"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#aec093859d42f0470c884edd1e976d9f3">oboe::AudioStream::stop</a></div><div class="ttdeci">virtual Result stop(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">oboe::AudioApi::AAudio</a></div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:31</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:33</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_afa35ee4b8629fbffe26b9be7c7ed55d2"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">oboe::AudioStream::getAvailableFrames</a></div><div class="ttdeci">ResultWithValue&lt; int32_t &gt; getAvailableFrames()</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a0faa6d3a6fd4f367e6f80d5a29e6dcba"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">oboe::AudioStream::setDataCallbackEnabled</a></div><div class="ttdeci">void setDataCallbackEnabled(bool enabled)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:478</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a15cdaaaa4c1e8da322d6da33334c8147"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">oboe::AudioStream::usesAAudio</a></div><div class="ttdeci">bool usesAAudio() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:358</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a0faa6d3a6fd4f367e6f80d5a29e6dcba"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">oboe::AudioStream::setDataCallbackEnabled</a></div><div class="ttdeci">void setDataCallbackEnabled(bool enabled)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:499</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a15cdaaaa4c1e8da322d6da33334c8147"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">oboe::AudioStream::usesAAudio</a></div><div class="ttdeci">bool usesAAudio() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:359</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a32c25c0333eab3d65ce02275ad4acb3d"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a32c25c0333eab3d65ce02275ad4acb3d">oboe::AudioStream::flush</a></div><div class="ttdeci">virtual Result flush(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a5c01907a59d5f89a5e4b819fe66b08bc"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">oboe::AudioStream::getBytesPerFrame</a></div><div class="ttdeci">int32_t getBytesPerFrame() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:216</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a6d8493f66a945cb426506c70f0358e5f"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">oboe::AudioStreamBase::mDataCallback</a></div><div class="ttdeci">AudioStreamDataCallback * mDataCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:182</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a5c01907a59d5f89a5e4b819fe66b08bc"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">oboe::AudioStream::getBytesPerFrame</a></div><div class="ttdeci">int32_t getBytesPerFrame() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:217</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_af04f03eb6b64b564f1c4401688987d21"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">oboe::AudioStream::start</a></div><div class="ttdeci">virtual Result start(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</div></div>
 <div class="ttc" id="namespaceoboe_html_aab8f5f081a8b2147e16ec920347c1b5c"><div class="ttname"><a href="namespaceoboe.html#aab8f5f081a8b2147e16ec920347c1b5c">oboe::kDefaultTimeoutNanos</a></div><div class="ttdeci">constexpr int64_t kDefaultTimeoutNanos</div><div class="ttdef"><b>Definition:</b> AudioStream.h:39</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_ad1a1d3bbf3b348ed92b7ed18ce9cc261"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">oboe::AudioStream::getXRunCount</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; getXRunCount() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:193</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a88a63317b7c58815bac074976b00aa23"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">oboe::AudioStream::mFramesWritten</a></div><div class="ttdeci">std::atomic&lt; int64_t &gt; mFramesWritten</div><div class="ttdef"><b>Definition:</b> AudioStream.h:488</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_ad1a1d3bbf3b348ed92b7ed18ce9cc261"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">oboe::AudioStream::getXRunCount</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; getXRunCount() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:194</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a88a63317b7c58815bac074976b00aa23"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">oboe::AudioStream::mFramesWritten</a></div><div class="ttdeci">std::atomic&lt; int64_t &gt; mFramesWritten</div><div class="ttdef"><b>Definition:</b> AudioStream.h:526</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_ab7a8cfe5d6039386bc5850fd5ee9bd62"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ab7a8cfe5d6039386bc5850fd5ee9bd62">oboe::AudioStream::fireDataCallback</a></div><div class="ttdeci">DataCallbackResult fireDataCallback(void *audioData, int numFrames)</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a5458d7130415eb4defe3dbc11d479e2f"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">oboe::AudioStream::getUnderlyingStream</a></div><div class="ttdeci">virtual void * getUnderlyingStream() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:370</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a5458d7130415eb4defe3dbc11d479e2f"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">oboe::AudioStream::getUnderlyingStream</a></div><div class="ttdeci">virtual void * getUnderlyingStream() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:371</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a64ad978c5f70ced17ef5a96605496515"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a64ad978c5f70ced17ef5a96605496515">oboe::AudioStream::updateFramesWritten</a></div><div class="ttdeci">virtual void updateFramesWritten()=0</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_ab43dd4074e1de57bac1c3fd111430341"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341">oboe::AudioStream::getFramesWritten</a></div><div class="ttdeci">virtual int64_t getFramesWritten()</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_afddb0962863ccf9ec6672a042fe15941"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">oboe::AudioStream::waitForAvailableFrames</a></div><div class="ttdeci">ResultWithValue&lt; int32_t &gt; waitForAvailableFrames(int32_t numFrames, int64_t timeoutNanoseconds)</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:33</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:156</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_data_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:34</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:190</div></div>
 <div class="ttc" id="namespaceoboe_html_af85fc9910a287df6c5df0ed396bb75cd"><div class="ttname"><a href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">oboe::DataCallbackResult</a></div><div class="ttdeci">DataCallbackResult</div><div class="ttdef"><b>Definition:</b> Definitions.h:119</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">oboe::AudioApi</a></div><div class="ttdeci">AudioApi</div><div class="ttdef"><b>Definition:</b> Definitions.h:213</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a8adbacd6a55a94a532916ab037fba1d6"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a8adbacd6a55a94a532916ab037fba1d6">oboe::AudioStream::waitForStateTransition</a></div><div class="ttdeci">virtual Result waitForStateTransition(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_ac160acb656515814fa6fdd157c131a0a"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a">oboe::AudioStream::getFramesPerBurst</a></div><div class="ttdeci">virtual int32_t getFramesPerBurst()=0</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a9c8ea30e30e513766d5e996c370eb8d8"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">oboe::AudioStream::close</a></div><div class="ttdeci">virtual Result close()</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a06e3f9e133b3a75515e7793939d1cd03"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">oboe::AudioStream::setBufferSizeInFrames</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; setBufferSizeInFrames(int32_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:177</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_ae023cb001f3261d064f423101798d6be"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">oboe::AudioStream::calculateLatencyMillis</a></div><div class="ttdeci">virtual ResultWithValue&lt; double &gt; calculateLatencyMillis()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:265</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_acb8edbc17ff79993a8ed996d216fe6f3"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">oboe::AudioStream::getTimestamp</a></div><div class="ttdeci">virtual Result getTimestamp(clockid_t, int64_t *, int64_t *)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:286</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a686c6ce8a29051c858fd1de386805dc6"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">oboe::AudioStream::open</a></div><div class="ttdeci">virtual Result open()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:66</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a06e3f9e133b3a75515e7793939d1cd03"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">oboe::AudioStream::setBufferSizeInFrames</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; setBufferSizeInFrames(int32_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:178</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_ae023cb001f3261d064f423101798d6be"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">oboe::AudioStream::calculateLatencyMillis</a></div><div class="ttdeci">virtual ResultWithValue&lt; double &gt; calculateLatencyMillis()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:266</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_acb8edbc17ff79993a8ed996d216fe6f3"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">oboe::AudioStream::getTimestamp</a></div><div class="ttdeci">virtual Result getTimestamp(clockid_t, int64_t *, int64_t *)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:287</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a686c6ce8a29051c858fd1de386805dc6"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">oboe::AudioStream::open</a></div><div class="ttdeci">virtual Result open()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:67</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_aeebfc59abd978cd6dff07c16cfe266df"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">oboe::AudioStream::getFramesRead</a></div><div class="ttdeci">virtual int64_t getFramesRead()</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html"><div class="ttname"><a href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:44</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_add85011ba825f74931deeb92c5edf831"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">oboe::AudioStream::isDataCallbackEnabled</a></div><div class="ttdeci">bool isDataCallbackEnabled()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:470</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a8089f0a0cb68d4039cf33e6584129978"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">oboe::AudioStream::read</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; read(void *, int32_t, int64_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:340</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_add85011ba825f74931deeb92c5edf831"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">oboe::AudioStream::isDataCallbackEnabled</a></div><div class="ttdeci">bool isDataCallbackEnabled()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:491</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a8089f0a0cb68d4039cf33e6584129978"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">oboe::AudioStream::read</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; read(void *, int32_t, int64_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:341</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a7f18bb3cc5490fd7fbc1f6da63c730f6"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a7f18bb3cc5490fd7fbc1f6da63c730f6">oboe::AudioStream::requestPause</a></div><div class="ttdeci">virtual Result requestPause()=0</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a3612c05ed6b01a213dde67d913c07e11"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">oboe::AudioStream::write</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; write(const void *, int32_t, int64_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:322</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_a07e82f9b9e2e4800f23ae9a7193c3b58"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">oboe::AudioStream::mFramesRead</a></div><div class="ttdeci">std::atomic&lt; int64_t &gt; mFramesRead</div><div class="ttdef"><b>Definition:</b> AudioStream.h:496</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a3612c05ed6b01a213dde67d913c07e11"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">oboe::AudioStream::write</a></div><div class="ttdeci">virtual ResultWithValue&lt; int32_t &gt; write(const void *, int32_t, int64_t)</div><div class="ttdef"><b>Definition:</b> AudioStream.h:323</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a07e82f9b9e2e4800f23ae9a7193c3b58"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">oboe::AudioStream::mFramesRead</a></div><div class="ttdeci">std::atomic&lt; int64_t &gt; mFramesRead</div><div class="ttdef"><b>Definition:</b> AudioStream.h:534</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_base_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:29</div></div>
 <div class="ttc" id="namespaceoboe_html_a831e887150474c087170679eaca8672b"><div class="ttname"><a href="namespaceoboe.html#a831e887150474c087170679eaca8672b">oboe::kNanosPerMillisecond</a></div><div class="ttdeci">constexpr int64_t kNanosPerMillisecond</div><div class="ttdef"><b>Definition:</b> Definitions.h:43</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a820e634f741e6b5efdcef8104cecb919"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a820e634f741e6b5efdcef8104cecb919">oboe::AudioStream::requestStop</a></div><div class="ttdeci">virtual Result requestStop()=0</div></div>
@@ -114,17 +115,18 @@
 <div class="ttc" id="classoboe_1_1_audio_stream_html_aa5f4801cca6877eeaa4735b93933269d"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#aa5f4801cca6877eeaa4735b93933269d">oboe::AudioStream::launchStopThread</a></div><div class="ttdeci">void launchStopThread()</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a0c865a5501f369d959c39d8ab8b46a07"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a0c865a5501f369d959c39d8ab8b46a07">oboe::AudioStream::waitForStateChange</a></div><div class="ttdeci">virtual Result waitForStateChange(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0</div></div>
 <div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
-<div class="ttc" id="structoboe_1_1_stream_deleter_functor_html"><div class="ttname"><a href="structoboe_1_1_stream_deleter_functor.html">oboe::StreamDeleterFunctor</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:513</div></div>
+<div class="ttc" id="structoboe_1_1_stream_deleter_functor_html"><div class="ttname"><a href="structoboe_1_1_stream_deleter_functor.html">oboe::StreamDeleterFunctor</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:555</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_html_aa48da7bf28026b7cccee73e6b054af28"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">oboe::AudioStream::wasErrorCallbackCalled</a></div><div class="ttdeci">bool wasErrorCallbackCalled()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:432</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_aa48da7bf28026b7cccee73e6b054af28"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">oboe::AudioStream::wasErrorCallbackCalled</a></div><div class="ttdeci">bool wasErrorCallbackCalled()</div><div class="ttdef"><b>Definition:</b> AudioStream.h:453</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a43d8a098440cde28f4ee8bedd6d107c4"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">oboe::AudioStream::isXRunCountSupported</a></div><div class="ttdeci">virtual bool isXRunCountSupported() const =0</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae3f72318212dd9977d7fa0ced92c91f4"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">oboe::AudioStreamBase::mStreamCallback</a></div><div class="ttdeci">AudioStreamCallback * mStreamCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:152</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a3c484e314dee8dfed1d419f487b5d601"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a3c484e314dee8dfed1d419f487b5d601">oboe::AudioStream::requestStart</a></div><div class="ttdeci">virtual Result requestStart()=0</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_html_a8fe8afdf164a1fe835c514f709743d75"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">oboe::AudioStream::getLastErrorCallbackResult</a></div><div class="ttdeci">virtual oboe::Result getLastErrorCallbackResult() const</div><div class="ttdef"><b>Definition:</b> AudioStream.h:438</div></div>
 <div class="ttc" id="namespaceoboe_html_a89fa2ce046723764618c29db737917f6"><div class="ttname"><a href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">oboe::StreamState</a></div><div class="ttdeci">StreamState</div><div class="ttdef"><b>Definition:</b> Definitions.h:58</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a9d37cc6513823c685ae892626ff83ea8"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a9d37cc6513823c685ae892626ff83ea8">oboe::AudioStream::getState</a></div><div class="ttdeci">virtual StreamState getState() const =0</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a04f29836748a8e5842aef2be200022ad"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a04f29836748a8e5842aef2be200022ad">oboe::AudioStream::pause</a></div><div class="ttdeci">virtual Result pause(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a6bd5d633ff999e4da1faf3cd949aa602"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a6bd5d633ff999e4da1faf3cd949aa602">oboe::AudioStream::requestFlush</a></div><div class="ttdeci">virtual Result requestFlush()=0</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a462358ddab709c79d1a7968d6d55b727"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">oboe::AudioStream::updateFramesRead</a></div><div class="ttdeci">virtual void updateFramesRead()=0</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_adc0c8cc54adb6d3350c62b8a74b9c57b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">oboe::AudioStreamBase::mErrorCallback</a></div><div class="ttdeci">AudioStreamErrorCallback * mErrorCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:185</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html_a44dda61e6e948e49b68f87172f084d62"><div class="ttname"><a href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">oboe::AudioStream::getBytesPerSample</a></div><div class="ttdeci">int32_t getBytesPerSample() const</div></div>
 <div class="ttc" id="classoboe_1_1_result_with_value_html"><div class="ttname"><a href="classoboe_1_1_result_with_value.html">oboe::ResultWithValue</a></div><div class="ttdef"><b>Definition:</b> ResultWithValue.h:47</div></div>
 </div><!-- fragment --></div><!-- contents -->
diff --git a/docs/reference/_audio_stream_base_8h_source.html b/docs/reference/_audio_stream_base_8h_source.html
index 0fe6e75..ce322da 100644
--- a/docs/reference/_audio_stream_base_8h_source.html
+++ b/docs/reference/_audio_stream_base_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,57 +71,69 @@
 <div class="title">AudioStreamBase.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2015 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_BASE_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_BASE_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;memory&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamCallback.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html">   29</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() {}</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;    <span class="comment">// This class only contains primitives so we can use default constructor and copy methods.</span></div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp;) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp; <a class="code" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp;) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">   51</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a>; }</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">   56</a></span>&#160;    <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a>; }</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">   61</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">getSampleRate</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a>; }</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;</div><div class="line"><a name="l00066"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">   66</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a>; }</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">   71</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a>; }</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00079"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">   79</a></span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>() { <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a>; }</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;</div><div class="line"><a name="l00084"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">   84</a></span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a>; }</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;</div><div class="line"><a name="l00089"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">   89</a></span>&#160;    <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">getSharingMode</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a>; }</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00094"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">   94</a></span>&#160;    <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">getPerformanceMode</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a>; }</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;</div><div class="line"><a name="l00099"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">   99</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a>; }</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;</div><div class="line"><a name="l00104"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">  104</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>* <a class="code" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a>;</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;    }</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;</div><div class="line"><a name="l00111"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">  111</a></span>&#160;    <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a>; }</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;</div><div class="line"><a name="l00116"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">  116</a></span>&#160;    <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a>; }</div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;</div><div class="line"><a name="l00121"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">  121</a></span>&#160;    <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a>; }</div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;</div><div class="line"><a name="l00126"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">  126</a></span>&#160;    <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">getSessionId</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a>; }</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;</div><div class="line"><a name="l00131"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">  131</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">isChannelConversionAllowed</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;        <span class="keywordflow">return</span> mChannelConversionAllowed;</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;    }</div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;</div><div class="line"><a name="l00138"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">  138</a></span>&#160;    <span class="keywordtype">bool</span>  <a class="code" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">isFormatConversionAllowed</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;        <span class="keywordflow">return</span> mFormatConversionAllowed;</div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;    }</div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;</div><div class="line"><a name="l00145"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">  145</a></span>&#160;    <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">getSampleRateConversionQuality</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;        <span class="keywordflow">return</span> mSampleRateConversionQuality;</div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;    }</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;</div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;<span class="keyword">protected</span>:</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;</div><div class="line"><a name="l00152"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">  152</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>            *<a class="code" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00154"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">  154</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00156"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">  156</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00158"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">  158</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00160"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">  160</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00162"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">  162</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00164"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">  164</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00169"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">  169</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;</div><div class="line"><a name="l00172"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">  172</a></span>&#160;    <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a> = <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca">SharingMode::Shared</a>;</div><div class="line"><a name="l00174"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">  174</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a> = AudioFormat::Unspecified;</div><div class="line"><a name="l00176"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">  176</a></span>&#160;    <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a>                       <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a> = <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">Direction::Output</a>;</div><div class="line"><a name="l00178"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">  178</a></span>&#160;    <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a>                 <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a> = PerformanceMode::None;</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;</div><div class="line"><a name="l00181"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">  181</a></span>&#160;    <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a>                           <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a> = <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">Usage::Media</a>;</div><div class="line"><a name="l00183"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">  183</a></span>&#160;    <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a> = ContentType::Music;</div><div class="line"><a name="l00187"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">  187</a></span>&#160;    <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a> = InputPreset::VoiceRecognition;</div><div class="line"><a name="l00189"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">  189</a></span>&#160;    <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a>                       <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a> = SessionId::None;</div><div class="line"><a name="l00190"></a><span class="lineno">  190</span>&#160;</div><div class="line"><a name="l00191"></a><span class="lineno">  191</span>&#160;    <span class="comment">// Control whether Oboe can convert channel counts to achieve optimal results.</span></div><div class="line"><a name="l00192"></a><span class="lineno">  192</span>&#160;    <span class="keywordtype">bool</span>                            mChannelConversionAllowed = <span class="keyword">false</span>;</div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;    <span class="comment">// Control whether Oboe can convert data formats to achieve optimal results.</span></div><div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;    <span class="keywordtype">bool</span>                            mFormatConversionAllowed = <span class="keyword">false</span>;</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;    <span class="comment">// Control whether and how Oboe can convert sample rates to achieve optimal results.</span></div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;    <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a>     mSampleRateConversionQuality = SampleRateConversionQuality::None;</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;};</div><div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;</div><div class="line"><a name="l00199"></a><span class="lineno">  199</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00200"></a><span class="lineno">  200</span>&#160;</div><div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_BASE_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_base_html_aa4ec3aa76e69350fbce6f00786211495"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">oboe::AudioStreamBase::isChannelConversionAllowed</a></div><div class="ttdeci">bool isChannelConversionAllowed() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:131</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3b65595d26d1eae1b8ce9925a5b98f6a"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">oboe::AudioStreamBase::mBufferSizeInFrames</a></div><div class="ttdeci">int32_t mBufferSizeInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:164</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2015 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_BASE_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_BASE_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;memory&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamCallback.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html">   29</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() {}</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;    <span class="comment">// This class only contains primitives so we can use default constructor and copy methods.</span></div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp;) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp; <a class="code" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>&amp;) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;</div><div class="line"><a name="l00052"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">   52</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a>; }</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;</div><div class="line"><a name="l00057"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">   57</a></span>&#160;    <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a>; }</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;</div><div class="line"><a name="l00062"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">   62</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">getSampleRate</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a>; }</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;</div><div class="line"><a name="l00067"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">   67</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a>(); }</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00072"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">   72</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a>; }</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">   77</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a>; }</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00085"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">   85</a></span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>() { <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a>; }</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;</div><div class="line"><a name="l00090"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">   90</a></span>&#160;    <span class="keyword">virtual</span> int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a>; }</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;</div><div class="line"><a name="l00095"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">   95</a></span>&#160;    <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">getSharingMode</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a>; }</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;</div><div class="line"><a name="l00100"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">  100</a></span>&#160;    <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">getPerformanceMode</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a>; }</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;</div><div class="line"><a name="l00105"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">  105</a></span>&#160;    int32_t <a class="code" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a>; }</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;</div><div class="line"><a name="l00111"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">  111</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *<a class="code" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a>;</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;    }</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;</div><div class="line"><a name="l00119"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">  119</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *<a class="code" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a>;</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;    }</div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;</div><div class="line"><a name="l00126"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">  126</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> != <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;    }</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;</div><div class="line"><a name="l00135"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">  135</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> != <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;    }</div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;</div><div class="line"><a name="l00142"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">  142</a></span>&#160;    <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a>; }</div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;</div><div class="line"><a name="l00147"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">  147</a></span>&#160;    <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a>; }</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;</div><div class="line"><a name="l00152"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">  152</a></span>&#160;    <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a>; }</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;</div><div class="line"><a name="l00157"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">  157</a></span>&#160;    <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">getSessionId</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a>; }</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;</div><div class="line"><a name="l00162"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">  162</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">isChannelConversionAllowed</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;        <span class="keywordflow">return</span> mChannelConversionAllowed;</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;    }</div><div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;</div><div class="line"><a name="l00169"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">  169</a></span>&#160;    <span class="keywordtype">bool</span>  <a class="code" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">isFormatConversionAllowed</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;        <span class="keywordflow">return</span> mFormatConversionAllowed;</div><div class="line"><a name="l00171"></a><span class="lineno">  171</span>&#160;    }</div><div class="line"><a name="l00172"></a><span class="lineno">  172</span>&#160;</div><div class="line"><a name="l00176"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">  176</a></span>&#160;    <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">getSampleRateConversionQuality</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;        <span class="keywordflow">return</span> mSampleRateConversionQuality;</div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;    }</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;<span class="keyword">protected</span>:</div><div class="line"><a name="l00182"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">  182</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a>        *<a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;</div><div class="line"><a name="l00185"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">  185</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a>       *<a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;</div><div class="line"><a name="l00188"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">  188</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00190"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">  190</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00192"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">  192</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00194"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">  194</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00196"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">  196</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00198"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">  198</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00203"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">  203</a></span>&#160;    int32_t                         <a class="code" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>;</div><div class="line"><a name="l00204"></a><span class="lineno">  204</span>&#160;</div><div class="line"><a name="l00206"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">  206</a></span>&#160;    <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a> = <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca">SharingMode::Shared</a>;</div><div class="line"><a name="l00208"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">  208</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a> = AudioFormat::Unspecified;</div><div class="line"><a name="l00210"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">  210</a></span>&#160;    <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a>                       <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a> = <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">Direction::Output</a>;</div><div class="line"><a name="l00212"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">  212</a></span>&#160;    <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a>                 <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a> = PerformanceMode::None;</div><div class="line"><a name="l00213"></a><span class="lineno">  213</span>&#160;</div><div class="line"><a name="l00215"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">  215</a></span>&#160;    <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a>                           <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a> = <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">Usage::Media</a>;</div><div class="line"><a name="l00217"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">  217</a></span>&#160;    <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a> = ContentType::Music;</div><div class="line"><a name="l00221"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">  221</a></span>&#160;    <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a>                     <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a> = InputPreset::VoiceRecognition;</div><div class="line"><a name="l00223"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">  223</a></span>&#160;    <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a>                       <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a> = SessionId::None;</div><div class="line"><a name="l00224"></a><span class="lineno">  224</span>&#160;</div><div class="line"><a name="l00225"></a><span class="lineno">  225</span>&#160;    <span class="comment">// Control whether Oboe can convert channel counts to achieve optimal results.</span></div><div class="line"><a name="l00226"></a><span class="lineno">  226</span>&#160;    <span class="keywordtype">bool</span>                            mChannelConversionAllowed = <span class="keyword">false</span>;</div><div class="line"><a name="l00227"></a><span class="lineno">  227</span>&#160;    <span class="comment">// Control whether Oboe can convert data formats to achieve optimal results.</span></div><div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;    <span class="keywordtype">bool</span>                            mFormatConversionAllowed = <span class="keyword">false</span>;</div><div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;    <span class="comment">// Control whether and how Oboe can convert sample rates to achieve optimal results.</span></div><div class="line"><a name="l00230"></a><span class="lineno">  230</span>&#160;    <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a>     mSampleRateConversionQuality = SampleRateConversionQuality::None;</div><div class="line"><a name="l00231"></a><span class="lineno">  231</span>&#160;</div><div class="line"><a name="l00233"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">  233</a></span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a>() {</div><div class="line"><a name="l00234"></a><span class="lineno">  234</span>&#160;        <span class="keywordflow">switch</span> (<a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a>) {</div><div class="line"><a name="l00235"></a><span class="lineno">  235</span>&#160;            <span class="keywordflow">case</span> AudioFormat::Unspecified:</div><div class="line"><a name="l00236"></a><span class="lineno">  236</span>&#160;            <span class="keywordflow">case</span> <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6abcd774f891b5f9df7099f3ea75dadf8d">AudioFormat::I16</a>:</div><div class="line"><a name="l00237"></a><span class="lineno">  237</span>&#160;            <span class="keywordflow">case</span> <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a22ae0e2b89e5e3d477f988cc36d3272b">AudioFormat::Float</a>:</div><div class="line"><a name="l00238"></a><span class="lineno">  238</span>&#160;                <span class="keywordflow">break</span>;</div><div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;</div><div class="line"><a name="l00240"></a><span class="lineno">  240</span>&#160;            <span class="keywordflow">default</span>:</div><div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;                <span class="keywordflow">return</span> Result::ErrorInvalidFormat;</div><div class="line"><a name="l00242"></a><span class="lineno">  242</span>&#160;        }</div><div class="line"><a name="l00243"></a><span class="lineno">  243</span>&#160;</div><div class="line"><a name="l00244"></a><span class="lineno">  244</span>&#160;        <span class="keywordflow">switch</span> (mSampleRateConversionQuality) {</div><div class="line"><a name="l00245"></a><span class="lineno">  245</span>&#160;            <span class="keywordflow">case</span> SampleRateConversionQuality::None:</div><div class="line"><a name="l00246"></a><span class="lineno">  246</span>&#160;            <span class="keywordflow">case</span> <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da90fd7fdf6f41406a75e5265b9583bb4e">SampleRateConversionQuality::Fastest</a>:</div><div class="line"><a name="l00247"></a><span class="lineno">  247</span>&#160;            <span class="keywordflow">case</span> SampleRateConversionQuality::Low:</div><div class="line"><a name="l00248"></a><span class="lineno">  248</span>&#160;            <span class="keywordflow">case</span> SampleRateConversionQuality::Medium:</div><div class="line"><a name="l00249"></a><span class="lineno">  249</span>&#160;            <span class="keywordflow">case</span> SampleRateConversionQuality::High:</div><div class="line"><a name="l00250"></a><span class="lineno">  250</span>&#160;            <span class="keywordflow">case</span> <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da68ef004de6166492c1d668eb8efe09bd">SampleRateConversionQuality::Best</a>:</div><div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;                <span class="keywordflow">return</span> Result::OK;</div><div class="line"><a name="l00252"></a><span class="lineno">  252</span>&#160;            <span class="keywordflow">default</span>:</div><div class="line"><a name="l00253"></a><span class="lineno">  253</span>&#160;                <span class="keywordflow">return</span> Result::ErrorIllegalArgument;</div><div class="line"><a name="l00254"></a><span class="lineno">  254</span>&#160;        }</div><div class="line"><a name="l00255"></a><span class="lineno">  255</span>&#160;    }</div><div class="line"><a name="l00256"></a><span class="lineno">  256</span>&#160;};</div><div class="line"><a name="l00257"></a><span class="lineno">  257</span>&#160;</div><div class="line"><a name="l00258"></a><span class="lineno">  258</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00259"></a><span class="lineno">  259</span>&#160;</div><div class="line"><a name="l00260"></a><span class="lineno">  260</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_BASE_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_base_html_a9fb2f34ae62dbda2c10e8513b754fa0c"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">oboe::AudioStreamBase::getDataCallback</a></div><div class="ttdeci">AudioStreamDataCallback * getDataCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:111</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_aa4ec3aa76e69350fbce6f00786211495"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">oboe::AudioStreamBase::isChannelConversionAllowed</a></div><div class="ttdeci">bool isChannelConversionAllowed() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:162</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3b65595d26d1eae1b8ce9925a5b98f6a"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">oboe::AudioStreamBase::mBufferSizeInFrames</a></div><div class="ttdeci">int32_t mBufferSizeInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:198</div></div>
 <div class="ttc" id="namespaceoboe_html_af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54"><div class="ttname"><a href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">oboe::Direction::Output</a></div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_abe1c1e9cada1ced9b5c1504ac9b07737"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">oboe::AudioStreamBase::mSessionId</a></div><div class="ttdeci">SessionId mSessionId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:189</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a26e9294721561d3b16bcaeec5faf4880"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase::mDirection</a></div><div class="ttdeci">Direction mDirection</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:176</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a093057d625bc896864b959974c265f21"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">oboe::AudioStreamBase::getDeviceId</a></div><div class="ttdeci">int32_t getDeviceId() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:99</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a7869f04836c2c2bdc10c7309ad4b8e09"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase::mFormat</a></div><div class="ttdeci">AudioFormat mFormat</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:174</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a8878a90949badbb5486cc2e022a57086"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">oboe::AudioStreamBase::getFramesPerCallback</a></div><div class="ttdeci">int32_t getFramesPerCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:66</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5f8f0e5add381b841856de80ea4cdb2b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase::mContentType</a></div><div class="ttdeci">ContentType mContentType</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:183</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_abe1c1e9cada1ced9b5c1504ac9b07737"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">oboe::AudioStreamBase::mSessionId</a></div><div class="ttdeci">SessionId mSessionId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:223</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a26e9294721561d3b16bcaeec5faf4880"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase::mDirection</a></div><div class="ttdeci">Direction mDirection</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:210</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a093057d625bc896864b959974c265f21"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">oboe::AudioStreamBase::getDeviceId</a></div><div class="ttdeci">int32_t getDeviceId() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:105</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a6d8493f66a945cb426506c70f0358e5f"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">oboe::AudioStreamBase::mDataCallback</a></div><div class="ttdeci">AudioStreamDataCallback * mDataCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:182</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a7869f04836c2c2bdc10c7309ad4b8e09"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase::mFormat</a></div><div class="ttdeci">AudioFormat mFormat</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:208</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_aef579f6d1f779c89d051f0963f2976b3"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">oboe::AudioStreamBase::isErrorCallbackSpecified</a></div><div class="ttdeci">bool isErrorCallbackSpecified() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:135</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a8878a90949badbb5486cc2e022a57086"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">oboe::AudioStreamBase::getFramesPerCallback</a></div><div class="ttdeci">int32_t getFramesPerCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:67</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5f8f0e5add381b841856de80ea4cdb2b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase::mContentType</a></div><div class="ttdeci">ContentType mContentType</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:217</div></div>
 <div class="ttc" id="namespaceoboe_html_a1068781f3920654b1bfd7ed136468184"><div class="ttname"><a href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">oboe::PerformanceMode</a></div><div class="ttdeci">PerformanceMode</div><div class="ttdef"><b>Definition:</b> Definitions.h:192</div></div>
 <div class="ttc" id="namespaceoboe_html_a5752250c10e96179e3618d7f72937eaf"><div class="ttname"><a href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">oboe::SessionId</a></div><div class="ttdeci">SessionId</div><div class="ttdef"><b>Definition:</b> Definitions.h:414</div></div>
 <div class="ttc" id="namespaceoboe_html_a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca"><div class="ttname"><a href="namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca">oboe::SharingMode::Shared</a></div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab99671c2d0552557e75dc7b4afe91765"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">oboe::AudioStreamBase::mPerformanceMode</a></div><div class="ttdeci">PerformanceMode mPerformanceMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:178</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a2ddb935de0e24dd7ae8e2cfbecac9fdc"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">oboe::AudioStreamBase::getPerformanceMode</a></div><div class="ttdeci">PerformanceMode getPerformanceMode() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:94</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a87e6bf37d6a2a5e983b8ca8d29aea575"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">oboe::AudioStreamBase::getChannelCount</a></div><div class="ttdeci">int32_t getChannelCount() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:51</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_aa3c502ce09bbad7690a2dd6acaf8892e"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">oboe::AudioStreamBase::getSessionId</a></div><div class="ttdeci">SessionId getSessionId() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:126</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:33</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9187492b679c97a0963e264954be473"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase::mSharingMode</a></div><div class="ttdeci">SharingMode mSharingMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:172</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:156</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ace3625a7332bf02a86818fdf63fcccb4"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">oboe::AudioStreamBase::isFormatConversionAllowed</a></div><div class="ttdeci">bool isFormatConversionAllowed() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:138</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab1e640461d7bf9d596decb913da7ac86"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">oboe::AudioStreamBase::getFormat</a></div><div class="ttdeci">AudioFormat getFormat() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:71</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab99671c2d0552557e75dc7b4afe91765"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">oboe::AudioStreamBase::mPerformanceMode</a></div><div class="ttdeci">PerformanceMode mPerformanceMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:212</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a2ddb935de0e24dd7ae8e2cfbecac9fdc"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">oboe::AudioStreamBase::getPerformanceMode</a></div><div class="ttdeci">PerformanceMode getPerformanceMode() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:100</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a87e6bf37d6a2a5e983b8ca8d29aea575"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">oboe::AudioStreamBase::getChannelCount</a></div><div class="ttdeci">int32_t getChannelCount() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:52</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_aa3c502ce09bbad7690a2dd6acaf8892e"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aa3c502ce09bbad7690a2dd6acaf8892e">oboe::AudioStreamBase::getSessionId</a></div><div class="ttdeci">SessionId getSessionId() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:157</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_data_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:34</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9187492b679c97a0963e264954be473"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase::mSharingMode</a></div><div class="ttdeci">SharingMode mSharingMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:206</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:190</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ace3625a7332bf02a86818fdf63fcccb4"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">oboe::AudioStreamBase::isFormatConversionAllowed</a></div><div class="ttdeci">bool isFormatConversionAllowed() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:169</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab1e640461d7bf9d596decb913da7ac86"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">oboe::AudioStreamBase::getFormat</a></div><div class="ttdeci">AudioFormat getFormat() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:77</div></div>
 <div class="ttc" id="namespaceoboe_html_a2a3cec6f021c1a324df60273710c604b"><div class="ttname"><a href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">oboe::ContentType</a></div><div class="ttdeci">ContentType</div><div class="ttdef"><b>Definition:</b> Definitions.h:339</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a23dafa12fb1a6242b088ebd5a52798c8"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase::mDeviceId</a></div><div class="ttdeci">int32_t mDeviceId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:160</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab12e2d068fa87e0553b01a400d96eb82"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">oboe::AudioStreamBase::getContentType</a></div><div class="ttdeci">ContentType getContentType() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:116</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5b518e82f39c9fcbd7050fd66adb253c"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase::mUsage</a></div><div class="ttdeci">Usage mUsage</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:181</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_abc3ee2815568b425d15a40e132aa8e38"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">oboe::AudioStreamBase::getFramesPerDataCallback</a></div><div class="ttdeci">int32_t getFramesPerDataCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:72</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a23dafa12fb1a6242b088ebd5a52798c8"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase::mDeviceId</a></div><div class="ttdeci">int32_t mDeviceId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:194</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5d5e07e98921d0193a5c0ccbe06f68c2"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">oboe::AudioStreamBase::isValidConfig</a></div><div class="ttdeci">virtual Result isValidConfig()</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:233</div></div>
+<div class="ttc" id="namespaceoboe_html_a82f3720eba7654aceb7282be36f9ff1da68ef004de6166492c1d668eb8efe09bd"><div class="ttname"><a href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da68ef004de6166492c1d668eb8efe09bd">oboe::SampleRateConversionQuality::Best</a></div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab12e2d068fa87e0553b01a400d96eb82"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">oboe::AudioStreamBase::getContentType</a></div><div class="ttdeci">ContentType getContentType() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:147</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5b518e82f39c9fcbd7050fd66adb253c"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase::mUsage</a></div><div class="ttdeci">Usage mUsage</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:215</div></div>
 <div class="ttc" id="namespaceoboe_html_a104ee8396c173fefac429759ea3c21a0"><div class="ttname"><a href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">oboe::Usage</a></div><div class="ttdeci">Usage</div><div class="ttdef"><b>Definition:</b> Definitions.h:263</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9d32f3e09174bad69e74f147ee33087"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">oboe::AudioStreamBase::getSampleRate</a></div><div class="ttdeci">int32_t getSampleRate() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:61</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a998885bb6c4f37e145f4626ad4177dea"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">oboe::AudioStreamBase::mSampleRate</a></div><div class="ttdeci">int32_t mSampleRate</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:158</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1b4a2a191546708da657510c3cd6b797"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">oboe::AudioStreamBase::getCallback</a></div><div class="ttdeci">AudioStreamCallback * getCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:104</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:97</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9d32f3e09174bad69e74f147ee33087"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">oboe::AudioStreamBase::getSampleRate</a></div><div class="ttdeci">int32_t getSampleRate() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:62</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a998885bb6c4f37e145f4626ad4177dea"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">oboe::AudioStreamBase::mSampleRate</a></div><div class="ttdeci">int32_t mSampleRate</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:192</div></div>
 <div class="ttc" id="namespaceoboe_html_a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74"><div class="ttname"><a href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">oboe::Usage::Media</a></div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a54061319ed348329a29d883a5de2482e"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">oboe::AudioStreamBase::mFramesPerBurst</a></div><div class="ttdeci">int32_t mFramesPerBurst</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:169</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1fb033fc963f971bd1aa8f6707e49b41"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">oboe::AudioStreamBase::getSharingMode</a></div><div class="ttdeci">SharingMode getSharingMode() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:89</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a54061319ed348329a29d883a5de2482e"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">oboe::AudioStreamBase::mFramesPerBurst</a></div><div class="ttdeci">int32_t mFramesPerBurst</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:203</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1fb033fc963f971bd1aa8f6707e49b41"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">oboe::AudioStreamBase::getSharingMode</a></div><div class="ttdeci">SharingMode getSharingMode() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:95</div></div>
+<div class="ttc" id="namespaceoboe_html_a92afc593e856571aacbfd02e57075df6abcd774f891b5f9df7099f3ea75dadf8d"><div class="ttname"><a href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6abcd774f891b5f9df7099f3ea75dadf8d">oboe::AudioFormat::I16</a></div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_base_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:29</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ac81d4719b350f8138aad1af38f0873b6"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">oboe::AudioStreamBase::mBufferCapacityInFrames</a></div><div class="ttdeci">int32_t mBufferCapacityInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:162</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1de8d6982d411a0cf50a32efba0ca3f2"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">oboe::AudioStreamBase::getSampleRateConversionQuality</a></div><div class="ttdeci">SampleRateConversionQuality getSampleRateConversionQuality() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:145</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ac81d4719b350f8138aad1af38f0873b6"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">oboe::AudioStreamBase::mBufferCapacityInFrames</a></div><div class="ttdeci">int32_t mBufferCapacityInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:196</div></div>
+<div class="ttc" id="namespaceoboe_html_a92afc593e856571aacbfd02e57075df6a22ae0e2b89e5e3d477f988cc36d3272b"><div class="ttname"><a href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a22ae0e2b89e5e3d477f988cc36d3272b">oboe::AudioFormat::Float</a></div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1de8d6982d411a0cf50a32efba0ca3f2"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">oboe::AudioStreamBase::getSampleRateConversionQuality</a></div><div class="ttdeci">SampleRateConversionQuality getSampleRateConversionQuality() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:176</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_base_html_aa9c987a59555d7a60b9f7a63f4afc7fc"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">oboe::AudioStreamBase::operator=</a></div><div class="ttdeci">AudioStreamBase &amp; operator=(const AudioStreamBase &amp;)=default</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_af5217ab05bfde0d7637024b599302d0b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">oboe::AudioStreamBase::getBufferSizeInFrames</a></div><div class="ttdeci">virtual int32_t getBufferSizeInFrames()</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:79</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_af5217ab05bfde0d7637024b599302d0b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">oboe::AudioStreamBase::getBufferSizeInFrames</a></div><div class="ttdeci">virtual int32_t getBufferSizeInFrames()</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:85</div></div>
 <div class="ttc" id="namespaceoboe_html_a92afc593e856571aacbfd02e57075df6"><div class="ttname"><a href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">oboe::AudioFormat</a></div><div class="ttdeci">AudioFormat</div><div class="ttdef"><b>Definition:</b> Definitions.h:94</div></div>
+<div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
 <div class="ttc" id="namespaceoboe_html_ab0772052200184e514082eaa89be7905"><div class="ttname"><a href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">oboe::kUnspecified</a></div><div class="ttdeci">constexpr int32_t kUnspecified</div><div class="ttdef"><b>Definition:</b> Definitions.h:32</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab1531253e64aaebe9e9eddbafb9098fc"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">oboe::AudioStreamBase::getBufferCapacityInFrames</a></div><div class="ttdeci">virtual int32_t getBufferCapacityInFrames() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:84</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab1531253e64aaebe9e9eddbafb9098fc"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">oboe::AudioStreamBase::getBufferCapacityInFrames</a></div><div class="ttdeci">virtual int32_t getBufferCapacityInFrames() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:90</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
 <div class="ttc" id="namespaceoboe_html_a82f3720eba7654aceb7282be36f9ff1d"><div class="ttname"><a href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">oboe::SampleRateConversionQuality</a></div><div class="ttdeci">SampleRateConversionQuality</div><div class="ttdef"><b>Definition:</b> Definitions.h:235</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1e5d4f5b30c4cc36f81ffd858cc00589"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">oboe::AudioStreamBase::mInputPreset</a></div><div class="ttdeci">InputPreset mInputPreset</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:187</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae3f72318212dd9977d7fa0ced92c91f4"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">oboe::AudioStreamBase::mStreamCallback</a></div><div class="ttdeci">AudioStreamCallback * mStreamCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:152</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1e5d4f5b30c4cc36f81ffd858cc00589"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">oboe::AudioStreamBase::mInputPreset</a></div><div class="ttdeci">InputPreset mInputPreset</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:221</div></div>
 <div class="ttc" id="namespaceoboe_html_af2147500089212955498a08ef2edb5ae"><div class="ttname"><a href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">oboe::Direction</a></div><div class="ttdeci">Direction</div><div class="ttdef"><b>Definition:</b> Definitions.h:78</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a6f86f2233a04c5a0b056f0c1c261f1b1"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">oboe::AudioStreamBase::getDirection</a></div><div class="ttdeci">Direction getDirection() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:56</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a6f86f2233a04c5a0b056f0c1c261f1b1"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">oboe::AudioStreamBase::getDirection</a></div><div class="ttdeci">Direction getDirection() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:57</div></div>
 <div class="ttc" id="namespaceoboe_html_a8330247b25429953a08354f41834d520"><div class="ttname"><a href="namespaceoboe.html#a8330247b25429953a08354f41834d520">oboe::SharingMode</a></div><div class="ttdeci">SharingMode</div><div class="ttdef"><b>Definition:</b> Definitions.h:167</div></div>
 <div class="ttc" id="namespaceoboe_html_a4477ed232b02e2694d9309baf55a8f06"><div class="ttname"><a href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">oboe::InputPreset</a></div><div class="ttdeci">InputPreset</div><div class="ttdef"><b>Definition:</b> Definitions.h:372</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3962eb94420ad0ecea70029236001899"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">oboe::AudioStreamBase::mFramesPerCallback</a></div><div class="ttdeci">int32_t mFramesPerCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:154</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a0bcfb2f8bd11c92b541fd910da9af397"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">oboe::AudioStreamBase::getUsage</a></div><div class="ttdeci">Usage getUsage() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:111</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5c773b93b8aa38191c7199cab023428a"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">oboe::AudioStreamBase::getInputPreset</a></div><div class="ttdeci">InputPreset getInputPreset() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:121</div></div>
+<div class="ttc" id="namespaceoboe_html_a82f3720eba7654aceb7282be36f9ff1da90fd7fdf6f41406a75e5265b9583bb4e"><div class="ttname"><a href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da90fd7fdf6f41406a75e5265b9583bb4e">oboe::SampleRateConversionQuality::Fastest</a></div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3962eb94420ad0ecea70029236001899"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">oboe::AudioStreamBase::mFramesPerCallback</a></div><div class="ttdeci">int32_t mFramesPerCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:188</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a9a54d38b985a2eb12c6972104dc0ce73"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">oboe::AudioStreamBase::isDataCallbackSpecified</a></div><div class="ttdeci">bool isDataCallbackSpecified() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:126</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a0bcfb2f8bd11c92b541fd910da9af397"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">oboe::AudioStreamBase::getUsage</a></div><div class="ttdeci">Usage getUsage() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:142</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_adc0c8cc54adb6d3350c62b8a74b9c57b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">oboe::AudioStreamBase::mErrorCallback</a></div><div class="ttdeci">AudioStreamErrorCallback * mErrorCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:185</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5c773b93b8aa38191c7199cab023428a"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">oboe::AudioStreamBase::getInputPreset</a></div><div class="ttdeci">InputPreset getInputPreset() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:152</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1328fb9288166ff325995ce1ea1867f0"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">oboe::AudioStreamBase::getErrorCallback</a></div><div class="ttdeci">AudioStreamErrorCallback * getErrorCallback() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:119</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/_audio_stream_builder_8h_source.html b/docs/reference/_audio_stream_builder_8h_source.html
index 26f8a47..9d354d3 100644
--- a/docs/reference/_audio_stream_builder_8h_source.html
+++ b/docs/reference/_audio_stream_builder_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,61 +71,67 @@
 <div class="title">AudioStreamBuilder.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2015 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_BUILDER_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_BUILDER_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBase.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;    <span class="comment">// This depends on AudioStream, so we use forward declaration, it will close and delete the stream</span></div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;    <span class="keyword">struct </span>StreamDeleterFunctor;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;    <span class="keyword">using</span> ManagedStream = std::unique_ptr&lt;AudioStream, StreamDeleterFunctor&gt;;</div><div class="line"><a name="l00031"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html">   31</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>() : <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() {}</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> &amp;audioStreamBase): <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>(audioStreamBase) {}</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00044"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">   44</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">setChannelCount</a>(<span class="keywordtype">int</span> channelCount) {</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = channelCount;</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;    }</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;</div><div class="line"><a name="l00054"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">   54</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">setDirection</a>(<a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> direction) {</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a> = direction;</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;    }</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;</div><div class="line"><a name="l00070"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">   70</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">setSampleRate</a>(int32_t sampleRate) {</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a> = sampleRate;</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;    }</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00089"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">   89</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">setFramesPerCallback</a>(<span class="keywordtype">int</span> framesPerCallback) {</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = framesPerCallback;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;    }</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;</div><div class="line"><a name="l00100"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">  100</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">setFormat</a>(<a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> format) {</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a> = format;</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;    }</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;</div><div class="line"><a name="l00117"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">  117</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">setBufferCapacityInFrames</a>(int32_t bufferCapacityInFrames) {</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a> = bufferCapacityInFrames;</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;    }</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;</div><div class="line"><a name="l00132"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">  132</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">getAudioApi</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> mAudioApi; }</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;</div><div class="line"><a name="l00147"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">  147</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">setAudioApi</a>(<a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> audioApi) {</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;        mAudioApi = audioApi;</div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;    }</div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">isAAudioSupported</a>();</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;</div><div class="line"><a name="l00169"></a><span class="lineno">  169</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">isAAudioRecommended</a>();</div><div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;</div><div class="line"><a name="l00179"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">  179</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">setSharingMode</a>(<a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> sharingMode) {</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a> = sharingMode;</div><div class="line"><a name="l00181"></a><span class="lineno">  181</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00182"></a><span class="lineno">  182</span>&#160;    }</div><div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;</div><div class="line"><a name="l00192"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">  192</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">setPerformanceMode</a>(<a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> performanceMode) {</div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a> = performanceMode;</div><div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;    }</div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;</div><div class="line"><a name="l00210"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">  210</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">setUsage</a>(<a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> usage) {</div><div class="line"><a name="l00211"></a><span class="lineno">  211</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a> = usage;</div><div class="line"><a name="l00212"></a><span class="lineno">  212</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00213"></a><span class="lineno">  213</span>&#160;    }</div><div class="line"><a name="l00214"></a><span class="lineno">  214</span>&#160;</div><div class="line"><a name="l00227"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">  227</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">setContentType</a>(<a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> contentType) {</div><div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a> = contentType;</div><div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00230"></a><span class="lineno">  230</span>&#160;    }</div><div class="line"><a name="l00231"></a><span class="lineno">  231</span>&#160;</div><div class="line"><a name="l00247"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">  247</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">setInputPreset</a>(<a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> inputPreset) {</div><div class="line"><a name="l00248"></a><span class="lineno">  248</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a> = inputPreset;</div><div class="line"><a name="l00249"></a><span class="lineno">  249</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00250"></a><span class="lineno">  250</span>&#160;    }</div><div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;</div><div class="line"><a name="l00276"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">  276</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">setSessionId</a>(<a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> sessionId) {</div><div class="line"><a name="l00277"></a><span class="lineno">  277</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a> = sessionId;</div><div class="line"><a name="l00278"></a><span class="lineno">  278</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00279"></a><span class="lineno">  279</span>&#160;    }</div><div class="line"><a name="l00280"></a><span class="lineno">  280</span>&#160;</div><div class="line"><a name="l00299"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">  299</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">setDeviceId</a>(int32_t deviceId) {</div><div class="line"><a name="l00300"></a><span class="lineno">  300</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a> = deviceId;</div><div class="line"><a name="l00301"></a><span class="lineno">  301</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00302"></a><span class="lineno">  302</span>&#160;    }</div><div class="line"><a name="l00303"></a><span class="lineno">  303</span>&#160;</div><div class="line"><a name="l00325"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">  325</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">setCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *streamCallback) {</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = streamCallback;</div><div class="line"><a name="l00327"></a><span class="lineno">  327</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00328"></a><span class="lineno">  328</span>&#160;    }</div><div class="line"><a name="l00329"></a><span class="lineno">  329</span>&#160;</div><div class="line"><a name="l00339"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">  339</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">setChannelConversionAllowed</a>(<span class="keywordtype">bool</span> allowed) {</div><div class="line"><a name="l00340"></a><span class="lineno">  340</span>&#160;        mChannelConversionAllowed = allowed;</div><div class="line"><a name="l00341"></a><span class="lineno">  341</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00342"></a><span class="lineno">  342</span>&#160;    }</div><div class="line"><a name="l00343"></a><span class="lineno">  343</span>&#160;</div><div class="line"><a name="l00351"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">  351</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">setFormatConversionAllowed</a>(<span class="keywordtype">bool</span> allowed) {</div><div class="line"><a name="l00352"></a><span class="lineno">  352</span>&#160;        mFormatConversionAllowed = allowed;</div><div class="line"><a name="l00353"></a><span class="lineno">  353</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00354"></a><span class="lineno">  354</span>&#160;    }</div><div class="line"><a name="l00355"></a><span class="lineno">  355</span>&#160;</div><div class="line"><a name="l00367"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">  367</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">setSampleRateConversionQuality</a>(<a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> quality) {</div><div class="line"><a name="l00368"></a><span class="lineno">  368</span>&#160;        mSampleRateConversionQuality = quality;</div><div class="line"><a name="l00369"></a><span class="lineno">  369</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00370"></a><span class="lineno">  370</span>&#160;    }</div><div class="line"><a name="l00371"></a><span class="lineno">  371</span>&#160;</div><div class="line"><a name="l00375"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">  375</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">willUseAAudio</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00376"></a><span class="lineno">  376</span>&#160;        <span class="keywordflow">return</span> (mAudioApi == <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AudioApi::AAudio</a> &amp;&amp; <a class="code" href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">isAAudioSupported</a>())</div><div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;                || (mAudioApi == AudioApi::Unspecified &amp;&amp; <a class="code" href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">isAAudioRecommended</a>());</div><div class="line"><a name="l00378"></a><span class="lineno">  378</span>&#160;    }</div><div class="line"><a name="l00379"></a><span class="lineno">  379</span>&#160;</div><div class="line"><a name="l00388"></a><span class="lineno">  388</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">openStream</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> **stream);</div><div class="line"><a name="l00389"></a><span class="lineno">  389</span>&#160;</div><div class="line"><a name="l00390"></a><span class="lineno">  390</span>&#160;</div><div class="line"><a name="l00400"></a><span class="lineno">  400</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff">openManagedStream</a>(ManagedStream &amp;stream);</div><div class="line"><a name="l00401"></a><span class="lineno">  401</span>&#160;</div><div class="line"><a name="l00402"></a><span class="lineno">  402</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00403"></a><span class="lineno">  403</span>&#160;</div><div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;    <span class="keywordtype">bool</span> isCompatible(<a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> &amp;other);</div><div class="line"><a name="l00409"></a><span class="lineno">  409</span>&#160;</div><div class="line"><a name="l00417"></a><span class="lineno">  417</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> *build();</div><div class="line"><a name="l00418"></a><span class="lineno">  418</span>&#160;</div><div class="line"><a name="l00419"></a><span class="lineno">  419</span>&#160;    <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a>       mAudioApi = AudioApi::Unspecified;</div><div class="line"><a name="l00420"></a><span class="lineno">  420</span>&#160;};</div><div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;</div><div class="line"><a name="l00422"></a><span class="lineno">  422</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00423"></a><span class="lineno">  423</span>&#160;</div><div class="line"><a name="l00424"></a><span class="lineno">  424</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_BUILDER_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_builder_html_af36ddcd00686a9e1de661bdac0685a8e"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">oboe::AudioStreamBuilder::setDeviceId</a></div><div class="ttdeci">AudioStreamBuilder * setDeviceId(int32_t deviceId)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:299</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2015 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_BUILDER_H_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_BUILDER_H_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStreamBase.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;ResultWithValue.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;    <span class="comment">// This depends on AudioStream, so we use forward declaration, it will close and delete the stream</span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;    <span class="keyword">struct </span>StreamDeleterFunctor;</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;    <span class="keyword">using</span> ManagedStream = std::unique_ptr&lt;AudioStream, StreamDeleterFunctor&gt;;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html">   33</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> {</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>() : <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>() {}</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>(<span class="keyword">const</span> <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> &amp;audioStreamBase): <a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a>(audioStreamBase) {}</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;</div><div class="line"><a name="l00046"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">   46</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">setChannelCount</a>(<span class="keywordtype">int</span> channelCount) {</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = channelCount;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    }</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">   56</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">setDirection</a>(<a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> direction) {</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a> = direction;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;    }</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;</div><div class="line"><a name="l00072"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">   72</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">setSampleRate</a>(int32_t sampleRate) {</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a> = sampleRate;</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;    }</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;</div><div class="line"><a name="l00080"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">   80</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">setFramesPerCallback</a>(<span class="keywordtype">int</span> framesPerCallback) {</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;        <span class="keywordflow">return</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">setFramesPerDataCallback</a>(framesPerCallback);</div><div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;    }</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;</div><div class="line"><a name="l00098"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">   98</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">setFramesPerDataCallback</a>(<span class="keywordtype">int</span> framesPerCallback) {</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = framesPerCallback;</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;    }</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;</div><div class="line"><a name="l00109"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">  109</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">setFormat</a>(<a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> format) {</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a> = format;</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;    }</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;</div><div class="line"><a name="l00126"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">  126</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">setBufferCapacityInFrames</a>(int32_t bufferCapacityInFrames) {</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a> = bufferCapacityInFrames;</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;    }</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;</div><div class="line"><a name="l00141"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">  141</a></span>&#160;    <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">getAudioApi</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> mAudioApi; }</div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;</div><div class="line"><a name="l00156"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">  156</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">setAudioApi</a>(<a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> audioApi) {</div><div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;        mAudioApi = audioApi;</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;    }</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;</div><div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">isAAudioSupported</a>();</div><div class="line"><a name="l00169"></a><span class="lineno">  169</span>&#160;</div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;    <span class="keyword">static</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">isAAudioRecommended</a>();</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;</div><div class="line"><a name="l00188"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">  188</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">setSharingMode</a>(<a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> sharingMode) {</div><div class="line"><a name="l00189"></a><span class="lineno">  189</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a> = sharingMode;</div><div class="line"><a name="l00190"></a><span class="lineno">  190</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00191"></a><span class="lineno">  191</span>&#160;    }</div><div class="line"><a name="l00192"></a><span class="lineno">  192</span>&#160;</div><div class="line"><a name="l00201"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">  201</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">setPerformanceMode</a>(<a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> performanceMode) {</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a> = performanceMode;</div><div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00204"></a><span class="lineno">  204</span>&#160;    }</div><div class="line"><a name="l00205"></a><span class="lineno">  205</span>&#160;</div><div class="line"><a name="l00206"></a><span class="lineno">  206</span>&#160;</div><div class="line"><a name="l00220"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">  220</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">setUsage</a>(<a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> usage) {</div><div class="line"><a name="l00221"></a><span class="lineno">  221</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a> = usage;</div><div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;    }</div><div class="line"><a name="l00224"></a><span class="lineno">  224</span>&#160;</div><div class="line"><a name="l00238"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">  238</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">setContentType</a>(<a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> contentType) {</div><div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a> = contentType;</div><div class="line"><a name="l00240"></a><span class="lineno">  240</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;    }</div><div class="line"><a name="l00242"></a><span class="lineno">  242</span>&#160;</div><div class="line"><a name="l00258"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">  258</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">setInputPreset</a>(<a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> inputPreset) {</div><div class="line"><a name="l00259"></a><span class="lineno">  259</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a> = inputPreset;</div><div class="line"><a name="l00260"></a><span class="lineno">  260</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00261"></a><span class="lineno">  261</span>&#160;    }</div><div class="line"><a name="l00262"></a><span class="lineno">  262</span>&#160;</div><div class="line"><a name="l00287"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">  287</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">setSessionId</a>(<a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> sessionId) {</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a> = sessionId;</div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00290"></a><span class="lineno">  290</span>&#160;    }</div><div class="line"><a name="l00291"></a><span class="lineno">  291</span>&#160;</div><div class="line"><a name="l00310"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">  310</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">setDeviceId</a>(int32_t deviceId) {</div><div class="line"><a name="l00311"></a><span class="lineno">  311</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a> = deviceId;</div><div class="line"><a name="l00312"></a><span class="lineno">  312</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00313"></a><span class="lineno">  313</span>&#160;    }</div><div class="line"><a name="l00314"></a><span class="lineno">  314</span>&#160;</div><div class="line"><a name="l00324"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">  324</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">setDataCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a> *dataCallback) {</div><div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = dataCallback;</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00327"></a><span class="lineno">  327</span>&#160;    }</div><div class="line"><a name="l00328"></a><span class="lineno">  328</span>&#160;</div><div class="line"><a name="l00344"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">  344</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">setErrorCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a> *errorCallback) {</div><div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = errorCallback;</div><div class="line"><a name="l00346"></a><span class="lineno">  346</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00347"></a><span class="lineno">  347</span>&#160;    }</div><div class="line"><a name="l00348"></a><span class="lineno">  348</span>&#160;</div><div class="line"><a name="l00372"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">  372</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">setCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *streamCallback) {</div><div class="line"><a name="l00373"></a><span class="lineno">  373</span>&#160;        <span class="comment">// Use the same callback object for both, dual inheritance.</span></div><div class="line"><a name="l00374"></a><span class="lineno">  374</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = streamCallback;</div><div class="line"><a name="l00375"></a><span class="lineno">  375</span>&#160;        <a class="code" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = streamCallback;</div><div class="line"><a name="l00376"></a><span class="lineno">  376</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;    }</div><div class="line"><a name="l00378"></a><span class="lineno">  378</span>&#160;</div><div class="line"><a name="l00388"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">  388</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">setChannelConversionAllowed</a>(<span class="keywordtype">bool</span> allowed) {</div><div class="line"><a name="l00389"></a><span class="lineno">  389</span>&#160;        mChannelConversionAllowed = allowed;</div><div class="line"><a name="l00390"></a><span class="lineno">  390</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00391"></a><span class="lineno">  391</span>&#160;    }</div><div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;</div><div class="line"><a name="l00400"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">  400</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">setFormatConversionAllowed</a>(<span class="keywordtype">bool</span> allowed) {</div><div class="line"><a name="l00401"></a><span class="lineno">  401</span>&#160;        mFormatConversionAllowed = allowed;</div><div class="line"><a name="l00402"></a><span class="lineno">  402</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00403"></a><span class="lineno">  403</span>&#160;    }</div><div class="line"><a name="l00404"></a><span class="lineno">  404</span>&#160;</div><div class="line"><a name="l00416"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">  416</a></span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *<a class="code" href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">setSampleRateConversionQuality</a>(<a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> quality) {</div><div class="line"><a name="l00417"></a><span class="lineno">  417</span>&#160;        mSampleRateConversionQuality = quality;</div><div class="line"><a name="l00418"></a><span class="lineno">  418</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">this</span>;</div><div class="line"><a name="l00419"></a><span class="lineno">  419</span>&#160;    }</div><div class="line"><a name="l00420"></a><span class="lineno">  420</span>&#160;</div><div class="line"><a name="l00424"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">  424</a></span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">willUseAAudio</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00425"></a><span class="lineno">  425</span>&#160;        <span class="keywordflow">return</span> (mAudioApi == <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AudioApi::AAudio</a> &amp;&amp; <a class="code" href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">isAAudioSupported</a>())</div><div class="line"><a name="l00426"></a><span class="lineno">  426</span>&#160;                || (mAudioApi == AudioApi::Unspecified &amp;&amp; <a class="code" href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">isAAudioRecommended</a>());</div><div class="line"><a name="l00427"></a><span class="lineno">  427</span>&#160;    }</div><div class="line"><a name="l00428"></a><span class="lineno">  428</span>&#160;</div><div class="line"><a name="l00438"></a><span class="lineno">  438</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">openStream</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> **stream);</div><div class="line"><a name="l00439"></a><span class="lineno">  439</span>&#160;</div><div class="line"><a name="l00450"></a><span class="lineno">  450</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">openStream</a>(std::shared_ptr&lt;oboe::AudioStream&gt; &amp;stream);</div><div class="line"><a name="l00451"></a><span class="lineno">  451</span>&#160;</div><div class="line"><a name="l00461"></a><span class="lineno">  461</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff">openManagedStream</a>(ManagedStream &amp;stream);</div><div class="line"><a name="l00462"></a><span class="lineno">  462</span>&#160;</div><div class="line"><a name="l00463"></a><span class="lineno">  463</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00464"></a><span class="lineno">  464</span>&#160;</div><div class="line"><a name="l00469"></a><span class="lineno">  469</span>&#160;    <span class="keywordtype">bool</span> isCompatible(<a class="code" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> &amp;other);</div><div class="line"><a name="l00470"></a><span class="lineno">  470</span>&#160;</div><div class="line"><a name="l00478"></a><span class="lineno">  478</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> *build();</div><div class="line"><a name="l00479"></a><span class="lineno">  479</span>&#160;</div><div class="line"><a name="l00480"></a><span class="lineno">  480</span>&#160;    <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a>       mAudioApi = AudioApi::Unspecified;</div><div class="line"><a name="l00481"></a><span class="lineno">  481</span>&#160;};</div><div class="line"><a name="l00482"></a><span class="lineno">  482</span>&#160;</div><div class="line"><a name="l00483"></a><span class="lineno">  483</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00484"></a><span class="lineno">  484</span>&#160;</div><div class="line"><a name="l00485"></a><span class="lineno">  485</span>&#160;<span class="preprocessor">#endif </span><span class="comment">/* OBOE_STREAM_BUILDER_H_ */</span><span class="preprocessor"></span></div><div class="ttc" id="classoboe_1_1_audio_stream_builder_html_af36ddcd00686a9e1de661bdac0685a8e"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">oboe::AudioStreamBuilder::setDeviceId</a></div><div class="ttdeci">AudioStreamBuilder * setDeviceId(int32_t deviceId)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:310</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">oboe::AudioApi::AAudio</a></div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:31</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_abe1c1e9cada1ced9b5c1504ac9b07737"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">oboe::AudioStreamBase::mSessionId</a></div><div class="ttdeci">SessionId mSessionId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:189</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a6cd1d65612e844e59da71a68ea0ab3ee"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">oboe::AudioStreamBuilder::setPerformanceMode</a></div><div class="ttdeci">AudioStreamBuilder * setPerformanceMode(PerformanceMode performanceMode)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:192</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a26e9294721561d3b16bcaeec5faf4880"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase::mDirection</a></div><div class="ttdeci">Direction mDirection</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:176</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a7869f04836c2c2bdc10c7309ad4b8e09"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase::mFormat</a></div><div class="ttdeci">AudioFormat mFormat</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:174</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5f8f0e5add381b841856de80ea4cdb2b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase::mContentType</a></div><div class="ttdeci">ContentType mContentType</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:183</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:33</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_abe1c1e9cada1ced9b5c1504ac9b07737"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">oboe::AudioStreamBase::mSessionId</a></div><div class="ttdeci">SessionId mSessionId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:223</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a6cd1d65612e844e59da71a68ea0ab3ee"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">oboe::AudioStreamBuilder::setPerformanceMode</a></div><div class="ttdeci">AudioStreamBuilder * setPerformanceMode(PerformanceMode performanceMode)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:201</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a26e9294721561d3b16bcaeec5faf4880"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase::mDirection</a></div><div class="ttdeci">Direction mDirection</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:210</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a6d8493f66a945cb426506c70f0358e5f"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">oboe::AudioStreamBase::mDataCallback</a></div><div class="ttdeci">AudioStreamDataCallback * mDataCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:182</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a7869f04836c2c2bdc10c7309ad4b8e09"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase::mFormat</a></div><div class="ttdeci">AudioFormat mFormat</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:208</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5f8f0e5add381b841856de80ea4cdb2b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase::mContentType</a></div><div class="ttdeci">ContentType mContentType</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:217</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a622732bbe5c6577356d749f7dc2108df"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">oboe::AudioStreamBuilder::isAAudioRecommended</a></div><div class="ttdeci">static bool isAAudioRecommended()</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_af7d24a9ec975d430732151e5ee0d1027"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">oboe::AudioStreamBuilder::setSampleRateConversionQuality</a></div><div class="ttdeci">AudioStreamBuilder * setSampleRateConversionQuality(SampleRateConversionQuality quality)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:367</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_af7d24a9ec975d430732151e5ee0d1027"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027">oboe::AudioStreamBuilder::setSampleRateConversionQuality</a></div><div class="ttdeci">AudioStreamBuilder * setSampleRateConversionQuality(SampleRateConversionQuality quality)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:416</div></div>
 <div class="ttc" id="namespaceoboe_html_a1068781f3920654b1bfd7ed136468184"><div class="ttname"><a href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">oboe::PerformanceMode</a></div><div class="ttdeci">PerformanceMode</div><div class="ttdef"><b>Definition:</b> Definitions.h:192</div></div>
 <div class="ttc" id="namespaceoboe_html_a5752250c10e96179e3618d7f72937eaf"><div class="ttname"><a href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">oboe::SessionId</a></div><div class="ttdeci">SessionId</div><div class="ttdef"><b>Definition:</b> Definitions.h:414</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a54c1651bdbe089d0d714af499e8a5f1d"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">oboe::AudioStreamBuilder::setSessionId</a></div><div class="ttdeci">AudioStreamBuilder * setSessionId(SessionId sessionId)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:276</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab99671c2d0552557e75dc7b4afe91765"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">oboe::AudioStreamBase::mPerformanceMode</a></div><div class="ttdeci">PerformanceMode mPerformanceMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:178</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:33</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9187492b679c97a0963e264954be473"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase::mSharingMode</a></div><div class="ttdeci">SharingMode mSharingMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:172</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a6a17bafc217c2b624179fbbf77fe4468"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">oboe::AudioStreamBuilder::setContentType</a></div><div class="ttdeci">AudioStreamBuilder * setContentType(ContentType contentType)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:227</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:156</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a54c1651bdbe089d0d714af499e8a5f1d"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d">oboe::AudioStreamBuilder::setSessionId</a></div><div class="ttdeci">AudioStreamBuilder * setSessionId(SessionId sessionId)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:287</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ab99671c2d0552557e75dc7b4afe91765"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">oboe::AudioStreamBase::mPerformanceMode</a></div><div class="ttdeci">PerformanceMode mPerformanceMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:212</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_data_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:34</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:181</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae9187492b679c97a0963e264954be473"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase::mSharingMode</a></div><div class="ttdeci">SharingMode mSharingMode</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:206</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a6a17bafc217c2b624179fbbf77fe4468"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">oboe::AudioStreamBuilder::setContentType</a></div><div class="ttdeci">AudioStreamBuilder * setContentType(ContentType contentType)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:238</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5ff460bac9d14dfeac4eeddfcbb6e206"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">oboe::AudioStreamBase::mChannelCount</a></div><div class="ttdeci">int32_t mChannelCount</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:190</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">oboe::AudioApi</a></div><div class="ttdeci">AudioApi</div><div class="ttdef"><b>Definition:</b> Definitions.h:213</div></div>
 <div class="ttc" id="namespaceoboe_html_a2a3cec6f021c1a324df60273710c604b"><div class="ttname"><a href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">oboe::ContentType</a></div><div class="ttdeci">ContentType</div><div class="ttdef"><b>Definition:</b> Definitions.h:339</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a593255a2f5eb972665775cfc5bc58f6a"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">oboe::AudioStreamBuilder::setUsage</a></div><div class="ttdeci">AudioStreamBuilder * setUsage(Usage usage)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:210</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a23dafa12fb1a6242b088ebd5a52798c8"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase::mDeviceId</a></div><div class="ttdeci">int32_t mDeviceId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:160</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a593255a2f5eb972665775cfc5bc58f6a"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">oboe::AudioStreamBuilder::setUsage</a></div><div class="ttdeci">AudioStreamBuilder * setUsage(Usage usage)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:220</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a23dafa12fb1a6242b088ebd5a52798c8"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase::mDeviceId</a></div><div class="ttdeci">int32_t mDeviceId</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:194</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a18e7b5f7554a4c2ca763e35e8117d699"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">oboe::AudioStreamBuilder::isAAudioSupported</a></div><div class="ttdeci">static bool isAAudioSupported()</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ad50f5d20cdf420d982bf499790cd3563"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">oboe::AudioStreamBuilder::setChannelConversionAllowed</a></div><div class="ttdeci">AudioStreamBuilder * setChannelConversionAllowed(bool allowed)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:339</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a3f397821f61eabaeedaf31064c859a54"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">oboe::AudioStreamBuilder::setFramesPerCallback</a></div><div class="ttdeci">AudioStreamBuilder * setFramesPerCallback(int framesPerCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:89</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ab3fbd47b06197619c26393637e26354c"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">oboe::AudioStreamBuilder::setDirection</a></div><div class="ttdeci">AudioStreamBuilder * setDirection(Direction direction)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:54</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_aa2e1d2d73cd6c2eb9f349bf2fe5f6515"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">oboe::AudioStreamBuilder::setFormat</a></div><div class="ttdeci">AudioStreamBuilder * setFormat(AudioFormat format)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:100</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5b518e82f39c9fcbd7050fd66adb253c"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase::mUsage</a></div><div class="ttdeci">Usage mUsage</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:181</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ad50f5d20cdf420d982bf499790cd3563"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">oboe::AudioStreamBuilder::setChannelConversionAllowed</a></div><div class="ttdeci">AudioStreamBuilder * setChannelConversionAllowed(bool allowed)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:388</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a3f397821f61eabaeedaf31064c859a54"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">oboe::AudioStreamBuilder::setFramesPerCallback</a></div><div class="ttdeci">AudioStreamBuilder * setFramesPerCallback(int framesPerCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:80</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ab3fbd47b06197619c26393637e26354c"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">oboe::AudioStreamBuilder::setDirection</a></div><div class="ttdeci">AudioStreamBuilder * setDirection(Direction direction)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:56</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_aa2e1d2d73cd6c2eb9f349bf2fe5f6515"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">oboe::AudioStreamBuilder::setFormat</a></div><div class="ttdeci">AudioStreamBuilder * setFormat(AudioFormat format)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:109</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a5b518e82f39c9fcbd7050fd66adb253c"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase::mUsage</a></div><div class="ttdeci">Usage mUsage</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:215</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html"><div class="ttname"><a href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:44</div></div>
 <div class="ttc" id="namespaceoboe_html_a104ee8396c173fefac429759ea3c21a0"><div class="ttname"><a href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">oboe::Usage</a></div><div class="ttdeci">Usage</div><div class="ttdef"><b>Definition:</b> Definitions.h:263</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a38c6d6c5e718df1e3ac69daaac47c391"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">oboe::AudioStreamBuilder::setAudioApi</a></div><div class="ttdeci">AudioStreamBuilder * setAudioApi(AudioApi audioApi)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:147</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a144a3d095fd668210282f1a91f23e1f0"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">oboe::AudioStreamBuilder::setInputPreset</a></div><div class="ttdeci">AudioStreamBuilder * setInputPreset(InputPreset inputPreset)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:247</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:97</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a38c6d6c5e718df1e3ac69daaac47c391"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">oboe::AudioStreamBuilder::setAudioApi</a></div><div class="ttdeci">AudioStreamBuilder * setAudioApi(AudioApi audioApi)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:156</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a144a3d095fd668210282f1a91f23e1f0"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">oboe::AudioStreamBuilder::setInputPreset</a></div><div class="ttdeci">AudioStreamBuilder * setInputPreset(InputPreset inputPreset)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:258</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a7ab172a9be4fca2489aa5cbcc48c20ff"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff">oboe::AudioStreamBuilder::openManagedStream</a></div><div class="ttdeci">Result openManagedStream(ManagedStream &amp;stream)</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a30ef3d5f51d56a9f980dc09600ed139d"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">oboe::AudioStreamBuilder::setSampleRate</a></div><div class="ttdeci">AudioStreamBuilder * setSampleRate(int32_t sampleRate)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:70</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a998885bb6c4f37e145f4626ad4177dea"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">oboe::AudioStreamBase::mSampleRate</a></div><div class="ttdeci">int32_t mSampleRate</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:158</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a30ef3d5f51d56a9f980dc09600ed139d"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">oboe::AudioStreamBuilder::setSampleRate</a></div><div class="ttdeci">AudioStreamBuilder * setSampleRate(int32_t sampleRate)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:72</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a998885bb6c4f37e145f4626ad4177dea"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">oboe::AudioStreamBase::mSampleRate</a></div><div class="ttdeci">int32_t mSampleRate</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:192</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_base_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:29</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ac81d4719b350f8138aad1af38f0873b6"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">oboe::AudioStreamBase::mBufferCapacityInFrames</a></div><div class="ttdeci">int32_t mBufferCapacityInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:162</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_abaff480867af51ca0899bfa6fd7cc3ef"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">oboe::AudioStreamBuilder::setBufferCapacityInFrames</a></div><div class="ttdeci">AudioStreamBuilder * setBufferCapacityInFrames(int32_t bufferCapacityInFrames)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:117</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ac81d4719b350f8138aad1af38f0873b6"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">oboe::AudioStreamBase::mBufferCapacityInFrames</a></div><div class="ttdeci">int32_t mBufferCapacityInFrames</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:196</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_abaff480867af51ca0899bfa6fd7cc3ef"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">oboe::AudioStreamBuilder::setBufferCapacityInFrames</a></div><div class="ttdeci">AudioStreamBuilder * setBufferCapacityInFrames(int32_t bufferCapacityInFrames)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:126</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_afb8e95e80df7edd1af27af490438785e"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">oboe::AudioStreamBuilder::setFramesPerDataCallback</a></div><div class="ttdeci">AudioStreamBuilder * setFramesPerDataCallback(int framesPerCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:98</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a86b94cfa47729bef2e04dce1a9086074"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">oboe::AudioStreamBuilder::openStream</a></div><div class="ttdeci">Result openStream(AudioStream **stream)</div></div>
 <div class="ttc" id="namespaceoboe_html_a92afc593e856571aacbfd02e57075df6"><div class="ttname"><a href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">oboe::AudioFormat</a></div><div class="ttdeci">AudioFormat</div><div class="ttdef"><b>Definition:</b> Definitions.h:94</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_aacb66f530bfc6f545911b5e169774567"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">oboe::AudioStreamBuilder::setErrorCallback</a></div><div class="ttdeci">AudioStreamBuilder * setErrorCallback(oboe::AudioStreamErrorCallback *errorCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:344</div></div>
 <div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a3e991742acbbfb6fe5ebcf592c478654"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">oboe::AudioStreamBuilder::setSharingMode</a></div><div class="ttdeci">AudioStreamBuilder * setSharingMode(SharingMode sharingMode)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:179</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a3e991742acbbfb6fe5ebcf592c478654"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654">oboe::AudioStreamBuilder::setSharingMode</a></div><div class="ttdeci">AudioStreamBuilder * setSharingMode(SharingMode sharingMode)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:188</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_aa07ea100fcb107d9f7913f206c2214f4"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">oboe::AudioStreamBuilder::willUseAAudio</a></div><div class="ttdeci">bool willUseAAudio() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:375</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_aa07ea100fcb107d9f7913f206c2214f4"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#aa07ea100fcb107d9f7913f206c2214f4">oboe::AudioStreamBuilder::willUseAAudio</a></div><div class="ttdeci">bool willUseAAudio() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:424</div></div>
 <div class="ttc" id="namespaceoboe_html_a82f3720eba7654aceb7282be36f9ff1d"><div class="ttname"><a href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">oboe::SampleRateConversionQuality</a></div><div class="ttdeci">SampleRateConversionQuality</div><div class="ttdef"><b>Definition:</b> Definitions.h:235</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1e5d4f5b30c4cc36f81ffd858cc00589"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">oboe::AudioStreamBase::mInputPreset</a></div><div class="ttdeci">InputPreset mInputPreset</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:187</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_ae3f72318212dd9977d7fa0ced92c91f4"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">oboe::AudioStreamBase::mStreamCallback</a></div><div class="ttdeci">AudioStreamCallback * mStreamCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:152</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a1e5d4f5b30c4cc36f81ffd858cc00589"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">oboe::AudioStreamBase::mInputPreset</a></div><div class="ttdeci">InputPreset mInputPreset</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:221</div></div>
 <div class="ttc" id="namespaceoboe_html_af2147500089212955498a08ef2edb5ae"><div class="ttname"><a href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">oboe::Direction</a></div><div class="ttdeci">Direction</div><div class="ttdef"><b>Definition:</b> Definitions.h:78</div></div>
 <div class="ttc" id="namespaceoboe_html_a8330247b25429953a08354f41834d520"><div class="ttname"><a href="namespaceoboe.html#a8330247b25429953a08354f41834d520">oboe::SharingMode</a></div><div class="ttdeci">SharingMode</div><div class="ttdef"><b>Definition:</b> Definitions.h:167</div></div>
 <div class="ttc" id="namespaceoboe_html_a4477ed232b02e2694d9309baf55a8f06"><div class="ttname"><a href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">oboe::InputPreset</a></div><div class="ttdeci">InputPreset</div><div class="ttdef"><b>Definition:</b> Definitions.h:372</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a075d10291e1f998d90c2f73ef767b5a7"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">oboe::AudioStreamBuilder::setChannelCount</a></div><div class="ttdeci">AudioStreamBuilder * setChannelCount(int channelCount)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:44</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a698cefa9af73bc97c020c004821fccbd"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">oboe::AudioStreamBuilder::setCallback</a></div><div class="ttdeci">AudioStreamBuilder * setCallback(AudioStreamCallback *streamCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:325</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3962eb94420ad0ecea70029236001899"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">oboe::AudioStreamBase::mFramesPerCallback</a></div><div class="ttdeci">int32_t mFramesPerCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:154</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a7ec5f427cd6fe55cb1ce536ff0cbb4d2"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">oboe::AudioStreamBuilder::setFormatConversionAllowed</a></div><div class="ttdeci">AudioStreamBuilder * setFormatConversionAllowed(bool allowed)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:351</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ac9d41811c297fd28bc61833f640bb8d0"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">oboe::AudioStreamBuilder::getAudioApi</a></div><div class="ttdeci">AudioApi getAudioApi() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:132</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a075d10291e1f998d90c2f73ef767b5a7"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">oboe::AudioStreamBuilder::setChannelCount</a></div><div class="ttdeci">AudioStreamBuilder * setChannelCount(int channelCount)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:46</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a698cefa9af73bc97c020c004821fccbd"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">oboe::AudioStreamBuilder::setCallback</a></div><div class="ttdeci">AudioStreamBuilder * setCallback(AudioStreamCallback *streamCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:372</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_acad307720e0f370267b4e2f9a626ae70"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">oboe::AudioStreamBuilder::setDataCallback</a></div><div class="ttdeci">AudioStreamBuilder * setDataCallback(oboe::AudioStreamDataCallback *dataCallback)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:324</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_a3962eb94420ad0ecea70029236001899"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">oboe::AudioStreamBase::mFramesPerCallback</a></div><div class="ttdeci">int32_t mFramesPerCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:188</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_a7ec5f427cd6fe55cb1ce536ff0cbb4d2"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">oboe::AudioStreamBuilder::setFormatConversionAllowed</a></div><div class="ttdeci">AudioStreamBuilder * setFormatConversionAllowed(bool allowed)</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:400</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_builder_html_ac9d41811c297fd28bc61833f640bb8d0"><div class="ttname"><a href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">oboe::AudioStreamBuilder::getAudioApi</a></div><div class="ttdeci">AudioApi getAudioApi() const</div><div class="ttdef"><b>Definition:</b> AudioStreamBuilder.h:141</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_base_html_adc0c8cc54adb6d3350c62b8a74b9c57b"><div class="ttname"><a href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">oboe::AudioStreamBase::mErrorCallback</a></div><div class="ttdeci">AudioStreamErrorCallback * mErrorCallback</div><div class="ttdef"><b>Definition:</b> AudioStreamBase.h:185</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/_audio_stream_callback_8h_source.html b/docs/reference/_audio_stream_callback_8h_source.html
index bb616bd..cb0e798 100644
--- a/docs/reference/_audio_stream_callback_8h_source.html
+++ b/docs/reference/_audio_stream_callback_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,14 +71,17 @@
 <div class="title">AudioStreamCallback.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright (C) 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_CALLBACK_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_CALLBACK_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">class </span>AudioStream;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_callback.html">   33</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> {</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">onAudioReady</a>(</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;            <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream,</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;            <span class="keywordtype">void</span> *audioData,</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;            int32_t numFrames) = 0;</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;</div><div class="line"><a name="l00103"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">  103</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">onErrorBeforeClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>* <span class="comment">/* oboeStream */</span>, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <span class="comment">/* error */</span>) {}</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;</div><div class="line"><a name="l00117"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">  117</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">onErrorAfterClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>* <span class="comment">/* oboeStream */</span>, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <span class="comment">/* error */</span>) {}</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;};</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;<span class="preprocessor">#endif //OBOE_STREAM_CALLBACK_H</span></div><div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:33</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright (C) 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STREAM_CALLBACK_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STREAM_CALLBACK_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">class </span>AudioStream;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_data_callback.html">   34</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> {</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;    <span class="keyword">virtual</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> <a class="code" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">onAudioReady</a>(</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;            <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *audioStream,</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;            <span class="keywordtype">void</span> *audioData,</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;            int32_t numFrames) = 0;</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;};</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;</div><div class="line"><a name="l00097"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_error_callback.html">   97</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> {</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;</div><div class="line"><a name="l00127"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">  127</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>* <span class="comment">/* audioStream */</span>, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <span class="comment">/* error */</span>) {</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;        <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;    }</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;</div><div class="line"><a name="l00147"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">  147</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>* <span class="comment">/* audioStream */</span>, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <span class="comment">/* error */</span>) {}</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;</div><div class="line"><a name="l00163"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">  163</a></span>&#160;    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>* <span class="comment">/* audioStream */</span>, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <span class="comment">/* error */</span>) {}</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;</div><div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;};</div><div class="line"><a name="l00166"></a><span class="lineno">  166</span>&#160;</div><div class="line"><a name="l00181"></a><span class="lineno"><a class="line" href="classoboe_1_1_audio_stream_callback.html">  181</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a>,</div><div class="line"><a name="l00182"></a><span class="lineno">  182</span>&#160;                            <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> {</div><div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00184"></a><span class="lineno">  184</span>&#160;    <span class="keyword">virtual</span> ~<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00185"></a><span class="lineno">  185</span>&#160;};</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;</div><div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;</div><div class="line"><a name="l00189"></a><span class="lineno">  189</span>&#160;<span class="preprocessor">#endif //OBOE_STREAM_CALLBACK_H</span></div><div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html_a5ad4b8936746ecbb2160a9389b117fc3"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">oboe::AudioStreamErrorCallback::onError</a></div><div class="ttdeci">virtual bool onError(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:127</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_data_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:34</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:181</div></div>
 <div class="ttc" id="namespaceoboe_html_af85fc9910a287df6c5df0ed396bb75cd"><div class="ttname"><a href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">oboe::DataCallbackResult</a></div><div class="ttdeci">DataCallbackResult</div><div class="ttdef"><b>Definition:</b> Definitions.h:119</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html_af3a7c44f0254abe6e5e5bb566e2317df"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">oboe::AudioStreamCallback::onAudioReady</a></div><div class="ttdeci">virtual DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames)=0</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html_a76bd3ef3e00396e10c21812003654cfe"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">oboe::AudioStreamErrorCallback::onErrorAfterClose</a></div><div class="ttdeci">virtual void onErrorAfterClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:163</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html"><div class="ttname"><a href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:44</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html_a57a1b21efc764e8bbf8d92008a993bfd"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">oboe::AudioStreamCallback::onErrorAfterClose</a></div><div class="ttdeci">virtual void onErrorAfterClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:117</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html_a77ceb641f941164d7b4d4c51c9a888b9"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">oboe::AudioStreamCallback::onErrorBeforeClose</a></div><div class="ttdeci">virtual void onErrorBeforeClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:103</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:97</div></div>
 <div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html_a4eb1e4916b71d8231e97b19898bc9bf0"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">oboe::AudioStreamErrorCallback::onErrorBeforeClose</a></div><div class="ttdeci">virtual void onErrorBeforeClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:147</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_data_callback_html_ad8a3a9f609df5fd3a5d885cbe1b2204d"><div class="ttname"><a href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">oboe::AudioStreamDataCallback::onAudioReady</a></div><div class="ttdeci">virtual DataCallbackResult onAudioReady(AudioStream *audioStream, void *audioData, int32_t numFrames)=0</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/_definitions_8h_source.html b/docs/reference/_definitions_8h_source.html
index 7a1fdcc..d24bd53 100644
--- a/docs/reference/_definitions_8h_source.html
+++ b/docs/reference/_definitions_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,9 +71,10 @@
 <div class="title">Definitions.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright (C) 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_DEFINITIONS_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_DEFINITIONS_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &lt;type_traits&gt;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="comment">// Oboe needs to be able to build on old NDKs so we use hard coded constants.</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="comment">// The correctness of these constants is verified in &quot;aaudio/AAudioLoader.cpp&quot;.</span></div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00032"></a><span class="lineno"><a class="line" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">   32</a></span>&#160;    constexpr int32_t <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a> = 0;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    <span class="comment">// TODO: Investigate using std::chrono</span></div><div class="line"><a name="l00038"></a><span class="lineno"><a class="line" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">   38</a></span>&#160;<span class="comment"></span>    constexpr int64_t <a class="code" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">kNanosPerMicrosecond</a> =    1000;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;</div><div class="line"><a name="l00043"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">   43</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a> =    <a class="code" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">kNanosPerMicrosecond</a> * 1000;</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno"><a class="line" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">   48</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">kMillisPerSecond</a> =        1000;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;</div><div class="line"><a name="l00053"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5948466b593c4eab65f7025846a39f51">   53</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#a5948466b593c4eab65f7025846a39f51">kNanosPerSecond</a> =         <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a> * <a class="code" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">kMillisPerSecond</a>;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;</div><div class="line"><a name="l00058"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">   58</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> : int32_t { <span class="comment">// aaudio_stream_state_t</span></div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;        Uninitialized = 0, <span class="comment">// AAUDIO_STREAM_STATE_UNINITIALIZED,</span></div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;        Unknown = 1, <span class="comment">// AAUDIO_STREAM_STATE_UNKNOWN,</span></div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;        Open = 2, <span class="comment">// AAUDIO_STREAM_STATE_OPEN,</span></div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;        Starting = 3, <span class="comment">// AAUDIO_STREAM_STATE_STARTING,</span></div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;        Started = 4, <span class="comment">// AAUDIO_STREAM_STATE_STARTED,</span></div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;        Pausing = 5, <span class="comment">// AAUDIO_STREAM_STATE_PAUSING,</span></div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;        Paused = 6, <span class="comment">// AAUDIO_STREAM_STATE_PAUSED,</span></div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;        Flushing = 7, <span class="comment">// AAUDIO_STREAM_STATE_FLUSHING,</span></div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;        Flushed = 8, <span class="comment">// AAUDIO_STREAM_STATE_FLUSHED,</span></div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;        Stopping = 9, <span class="comment">// AAUDIO_STREAM_STATE_STOPPING,</span></div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;        Stopped = 10, <span class="comment">// AAUDIO_STREAM_STATE_STOPPED,</span></div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;        Closing = 11, <span class="comment">// AAUDIO_STREAM_STATE_CLOSING,</span></div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;        Closed = 12, <span class="comment">// AAUDIO_STREAM_STATE_CLOSED,</span></div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;        Disconnected = 13, <span class="comment">// AAUDIO_STREAM_STATE_DISCONNECTED,</span></div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;    };</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00078"></a><span class="lineno"><a class="line" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">   78</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> : int32_t { <span class="comment">// aaudio_direction_t</span></div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;        <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">Output</a> = 0, <span class="comment">// AAUDIO_DIRECTION_OUTPUT,</span></div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;        <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea324118a6721dd6b8a9b9f4e327df2bf5">Input</a> = 1, <span class="comment">// AAUDIO_DIRECTION_INPUT,</span></div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;    };</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00094"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">   94</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> : int32_t { <span class="comment">// aaudio_format_t</span></div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a4bbb8f967da6d1a610596d7257179c2b">Invalid</a> = -1, <span class="comment">// AAUDIO_FORMAT_INVALID,</span></div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;        <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = 0, <span class="comment">// AAUDIO_FORMAT_UNSPECIFIED,</span></div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6abcd774f891b5f9df7099f3ea75dadf8d">I16</a> = 1, <span class="comment">// AAUDIO_FORMAT_PCM_I16,</span></div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a22ae0e2b89e5e3d477f988cc36d3272b">Float</a> = 2, <span class="comment">// AAUDIO_FORMAT_PCM_FLOAT,</span></div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;    };</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00119"></a><span class="lineno"><a class="line" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">  119</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> : int32_t { <span class="comment">// aaudio_data_callback_result_t</span></div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;        <span class="comment">// Indicates to the caller that the callbacks should continue.</span></div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;        Continue = 0, <span class="comment">// AAUDIO_CALLBACK_RESULT_CONTINUE,</span></div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;        <span class="comment">// Indicates to the caller that the callbacks should stop immediately.</span></div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;        Stop = 1, <span class="comment">// AAUDIO_CALLBACK_RESULT_STOP,</span></div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;    };</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;</div><div class="line"><a name="l00131"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">  131</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> : int32_t { <span class="comment">// aaudio_result_t</span></div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;        OK = 0, <span class="comment">// AAUDIO_OK</span></div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;        ErrorBase = -900, <span class="comment">// AAUDIO_ERROR_BASE,</span></div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;        ErrorDisconnected = -899, <span class="comment">// AAUDIO_ERROR_DISCONNECTED,</span></div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;        ErrorIllegalArgument = -898, <span class="comment">// AAUDIO_ERROR_ILLEGAL_ARGUMENT,</span></div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;        ErrorInternal = -896, <span class="comment">// AAUDIO_ERROR_INTERNAL,</span></div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;        ErrorInvalidState = -895, <span class="comment">// AAUDIO_ERROR_INVALID_STATE,</span></div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;        ErrorInvalidHandle = -892, <span class="comment">// AAUDIO_ERROR_INVALID_HANDLE,</span></div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;        ErrorUnimplemented = -890, <span class="comment">// AAUDIO_ERROR_UNIMPLEMENTED,</span></div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;        ErrorUnavailable = -889, <span class="comment">// AAUDIO_ERROR_UNAVAILABLE,</span></div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;        ErrorNoFreeHandles = -888, <span class="comment">// AAUDIO_ERROR_NO_FREE_HANDLES,</span></div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;        ErrorNoMemory = -887, <span class="comment">// AAUDIO_ERROR_NO_MEMORY,</span></div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;        ErrorNull = -886, <span class="comment">// AAUDIO_ERROR_NULL,</span></div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;        ErrorTimeout = -885, <span class="comment">// AAUDIO_ERROR_TIMEOUT,</span></div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;        ErrorWouldBlock = -884, <span class="comment">// AAUDIO_ERROR_WOULD_BLOCK,</span></div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;        ErrorInvalidFormat = -883, <span class="comment">// AAUDIO_ERROR_INVALID_FORMAT,</span></div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;        ErrorOutOfRange = -882, <span class="comment">// AAUDIO_ERROR_OUT_OF_RANGE,</span></div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;        ErrorNoService = -881, <span class="comment">// AAUDIO_ERROR_NO_SERVICE,</span></div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;        ErrorInvalidRate = -880, <span class="comment">// AAUDIO_ERROR_INVALID_RATE,</span></div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;        <span class="comment">// Reserved for future AAudio result types</span></div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;        Reserved1,</div><div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;        Reserved2,</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;        Reserved3,</div><div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;        Reserved4,</div><div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;        Reserved5,</div><div class="line"><a name="l00156"></a><span class="lineno">  156</span>&#160;        Reserved6,</div><div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;        Reserved7,</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;        Reserved8,</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;        Reserved9,</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;        Reserved10,</div><div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;        ErrorClosed,</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;    };</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;</div><div class="line"><a name="l00167"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">  167</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> : int32_t { <span class="comment">// aaudio_sharing_mode_t</span></div><div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;</div><div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;        <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520a2ef50b4c466304dc6ac77bac8a779971">Exclusive</a> = 0, <span class="comment">// AAUDIO_SHARING_MODE_EXCLUSIVE,</span></div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;        <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca">Shared</a> = 1, <span class="comment">// AAUDIO_SHARING_MODE_SHARED,</span></div><div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;    };</div><div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;</div><div class="line"><a name="l00192"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">  192</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> : int32_t { <span class="comment">// aaudio_performance_mode_t</span></div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;        <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a> = 10, <span class="comment">// AAUDIO_PERFORMANCE_MODE_NONE,</span></div><div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;        <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184abbad080463ed11f9d77797c04aa1e5b1">PowerSaving</a> = 11, <span class="comment">// AAUDIO_PERFORMANCE_MODE_POWER_SAVING,</span></div><div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;        <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184a611907b5ab1865515c35357efa41a9b9">LowLatency</a> = 12, <span class="comment">// AAUDIO_PERFORMANCE_MODE_LOW_LATENCY</span></div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;    };</div><div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;</div><div class="line"><a name="l00213"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">  213</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> : int32_t {</div><div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;        <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>,</div><div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;</div><div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;        <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a24e758ea9c1e842ef71cc8ff8b63fa9b">OpenSLES</a>,</div><div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;</div><div class="line"><a name="l00227"></a><span class="lineno">  227</span>&#160;        <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AAudio</a></div><div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;    };</div><div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;</div><div class="line"><a name="l00235"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">  235</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> : int32_t {</div><div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;        <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a>,</div><div class="line"><a name="l00244"></a><span class="lineno">  244</span>&#160;        <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da90fd7fdf6f41406a75e5265b9583bb4e">Fastest</a>,</div><div class="line"><a name="l00245"></a><span class="lineno">  245</span>&#160;        Low,</div><div class="line"><a name="l00246"></a><span class="lineno">  246</span>&#160;        Medium,</div><div class="line"><a name="l00247"></a><span class="lineno">  247</span>&#160;        High,</div><div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;        <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da68ef004de6166492c1d668eb8efe09bd">Best</a>,</div><div class="line"><a name="l00252"></a><span class="lineno">  252</span>&#160;    };</div><div class="line"><a name="l00253"></a><span class="lineno">  253</span>&#160;</div><div class="line"><a name="l00263"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">  263</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> : int32_t { <span class="comment">// aaudio_usage_t</span></div><div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">Media</a> =  1, <span class="comment">// AAUDIO_USAGE_MEDIA</span></div><div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;</div><div class="line"><a name="l00272"></a><span class="lineno">  272</span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">VoiceCommunication</a> = 2, <span class="comment">// AAUDIO_USAGE_VOICE_COMMUNICATION</span></div><div class="line"><a name="l00273"></a><span class="lineno">  273</span>&#160;</div><div class="line"><a name="l00277"></a><span class="lineno">  277</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a404f62633744bf4da0c6a27a2b78ce74">VoiceCommunicationSignalling</a> = 3, <span class="comment">// AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING</span></div><div class="line"><a name="l00278"></a><span class="lineno">  278</span>&#160;</div><div class="line"><a name="l00282"></a><span class="lineno">  282</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a46c4c4d980dfe025ae5b35aa0011dde4">Alarm</a> = 4, <span class="comment">// AAUDIO_USAGE_ALARM</span></div><div class="line"><a name="l00283"></a><span class="lineno">  283</span>&#160;</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a96d008db67fc0b5551a926842bbb6a71">Notification</a> = 5, <span class="comment">// AAUDIO_USAGE_NOTIFICATION</span></div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;</div><div class="line"><a name="l00293"></a><span class="lineno">  293</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a4e7a4b08274d472394b740a20d3bbdaf">NotificationRingtone</a> = 6, <span class="comment">// AAUDIO_USAGE_NOTIFICATION_RINGTONE</span></div><div class="line"><a name="l00294"></a><span class="lineno">  294</span>&#160;</div><div class="line"><a name="l00298"></a><span class="lineno">  298</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a089240b5380dbd12f1eac0ec258a3b2f">NotificationEvent</a> = 10, <span class="comment">// AAUDIO_USAGE_NOTIFICATION_EVENT</span></div><div class="line"><a name="l00299"></a><span class="lineno">  299</span>&#160;</div><div class="line"><a name="l00303"></a><span class="lineno">  303</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a639ffd54516c1a84a288a363c9469df8">AssistanceAccessibility</a> = 11, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY</span></div><div class="line"><a name="l00304"></a><span class="lineno">  304</span>&#160;</div><div class="line"><a name="l00308"></a><span class="lineno">  308</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0ade058a1314f9a8504593259ff4f21a1e">AssistanceNavigationGuidance</a> = 12, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE</span></div><div class="line"><a name="l00309"></a><span class="lineno">  309</span>&#160;</div><div class="line"><a name="l00313"></a><span class="lineno">  313</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a1ce57a0572748beebfc0c664ca1077e7">AssistanceSonification</a> = 13, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_SONIFICATION</span></div><div class="line"><a name="l00314"></a><span class="lineno">  314</span>&#160;</div><div class="line"><a name="l00318"></a><span class="lineno">  318</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a63d72051e901c069f8aa1b32aa0c43bb">Game</a> = 14, <span class="comment">// AAUDIO_USAGE_GAME</span></div><div class="line"><a name="l00319"></a><span class="lineno">  319</span>&#160;</div><div class="line"><a name="l00323"></a><span class="lineno">  323</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a9b1363da9503dbd4142c0274a88e8d4b">Assistant</a> = 16, <span class="comment">// AAUDIO_USAGE_ASSISTANT</span></div><div class="line"><a name="l00324"></a><span class="lineno">  324</span>&#160;    };</div><div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;</div><div class="line"><a name="l00339"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">  339</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> : int32_t { <span class="comment">// aaudio_content_type_t</span></div><div class="line"><a name="l00340"></a><span class="lineno">  340</span>&#160;</div><div class="line"><a name="l00344"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba3dc48a4b4619aa4edd1da7b937b4dcd1">  344</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba3dc48a4b4619aa4edd1da7b937b4dcd1">Speech</a> = 1, <span class="comment">// AAUDIO_CONTENT_TYPE_SPEECH</span></div><div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;</div><div class="line"><a name="l00349"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604bac156fcc7b29059305cef26f3904d4517">  349</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604bac156fcc7b29059305cef26f3904d4517">Music</a> = 2, <span class="comment">// AAUDIO_CONTENT_TYPE_MUSIC</span></div><div class="line"><a name="l00350"></a><span class="lineno">  350</span>&#160;</div><div class="line"><a name="l00354"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba8b3b366178c2b7b1688bca6cd33758b1">  354</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba8b3b366178c2b7b1688bca6cd33758b1">Movie</a> = 3, <span class="comment">// AAUDIO_CONTENT_TYPE_MOVIE</span></div><div class="line"><a name="l00355"></a><span class="lineno">  355</span>&#160;</div><div class="line"><a name="l00360"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba0885eef555037e94a7cf39fe683c2799">  360</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba0885eef555037e94a7cf39fe683c2799">Sonification</a> = 4, <span class="comment">// AAUDIO_CONTENT_TYPE_SONIFICATION</span></div><div class="line"><a name="l00361"></a><span class="lineno">  361</span>&#160;    };</div><div class="line"><a name="l00362"></a><span class="lineno">  362</span>&#160;</div><div class="line"><a name="l00372"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">  372</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> : int32_t { <span class="comment">// aaudio_input_preset_t</span></div><div class="line"><a name="l00376"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">  376</a></span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">Generic</a> = 1, <span class="comment">// AAUDIO_INPUT_PRESET_GENERIC</span></div><div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;</div><div class="line"><a name="l00381"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a6e8ef178769235d18b44fe2bb5ab33fe">  381</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a6e8ef178769235d18b44fe2bb5ab33fe">Camcorder</a> = 5, <span class="comment">// AAUDIO_INPUT_PRESET_CAMCORDER</span></div><div class="line"><a name="l00382"></a><span class="lineno">  382</span>&#160;</div><div class="line"><a name="l00386"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc">  386</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc">VoiceRecognition</a> = 6, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_RECOGNITION</span></div><div class="line"><a name="l00387"></a><span class="lineno">  387</span>&#160;</div><div class="line"><a name="l00391"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">  391</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">VoiceCommunication</a> = 7, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION</span></div><div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;</div><div class="line"><a name="l00398"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06acad9424158aefae0af7975901b11d85f">  398</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06acad9424158aefae0af7975901b11d85f">Unprocessed</a> = 9, <span class="comment">// AAUDIO_INPUT_PRESET_UNPROCESSED</span></div><div class="line"><a name="l00399"></a><span class="lineno">  399</span>&#160;</div><div class="line"><a name="l00405"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06ad19edec0a23e435c774bf3bbcf1d999c">  405</a></span>&#160;         <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06ad19edec0a23e435c774bf3bbcf1d999c">VoicePerformance</a> = 10, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE</span></div><div class="line"><a name="l00406"></a><span class="lineno">  406</span>&#160;</div><div class="line"><a name="l00407"></a><span class="lineno">  407</span>&#160;    };</div><div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;</div><div class="line"><a name="l00414"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">  414</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> {</div><div class="line"><a name="l00420"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">  420</a></span>&#160;         <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a> = -1, <span class="comment">// AAUDIO_SESSION_ID_NONE</span></div><div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;</div><div class="line"><a name="l00429"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123">  429</a></span>&#160;         <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123">Allocate</a> = 0, <span class="comment">// AAUDIO_SESSION_ID_ALLOCATE</span></div><div class="line"><a name="l00430"></a><span class="lineno">  430</span>&#160;    };</div><div class="line"><a name="l00431"></a><span class="lineno">  431</span>&#160;</div><div class="line"><a name="l00442"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029">  442</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029">ChannelCount</a> : int32_t {</div><div class="line"><a name="l00446"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">  446</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>,</div><div class="line"><a name="l00447"></a><span class="lineno">  447</span>&#160;</div><div class="line"><a name="l00451"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a8be103218645e121b51078620f452c79">  451</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a8be103218645e121b51078620f452c79">Mono</a> = 1,</div><div class="line"><a name="l00452"></a><span class="lineno">  452</span>&#160;</div><div class="line"><a name="l00456"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a534e646333ca7568317b171ea96b89ba">  456</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a534e646333ca7568317b171ea96b89ba">Stereo</a> = 2,</div><div class="line"><a name="l00457"></a><span class="lineno">  457</span>&#160;    };</div><div class="line"><a name="l00458"></a><span class="lineno">  458</span>&#160;</div><div class="line"><a name="l00477"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html">  477</a></span>&#160;    <span class="keyword">class </span><a class="code" href="classoboe_1_1_default_stream_values.html">DefaultStreamValues</a> {</div><div class="line"><a name="l00478"></a><span class="lineno">  478</span>&#160;</div><div class="line"><a name="l00479"></a><span class="lineno">  479</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l00480"></a><span class="lineno">  480</span>&#160;</div><div class="line"><a name="l00482"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#a46a5d9a653f2153f618cadcab764e1b1">  482</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#a46a5d9a653f2153f618cadcab764e1b1">SampleRate</a>;</div><div class="line"><a name="l00484"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#ab5ea5576699cebc56193f5c297d3e300">  484</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#ab5ea5576699cebc56193f5c297d3e300">FramesPerBurst</a>;</div><div class="line"><a name="l00486"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#ad5dce538d5963c81bf58350ab730962d">  486</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#ad5dce538d5963c81bf58350ab730962d">ChannelCount</a>;</div><div class="line"><a name="l00487"></a><span class="lineno">  487</span>&#160;</div><div class="line"><a name="l00488"></a><span class="lineno">  488</span>&#160;    };</div><div class="line"><a name="l00489"></a><span class="lineno">  489</span>&#160;</div><div class="line"><a name="l00493"></a><span class="lineno"><a class="line" href="structoboe_1_1_frame_timestamp.html">  493</a></span>&#160;    <span class="keyword">struct </span><a class="code" href="structoboe_1_1_frame_timestamp.html">FrameTimestamp</a> {</div><div class="line"><a name="l00494"></a><span class="lineno">  494</span>&#160;        int64_t position; <span class="comment">// in frames</span></div><div class="line"><a name="l00495"></a><span class="lineno">  495</span>&#160;        int64_t timestamp; <span class="comment">// in nanoseconds</span></div><div class="line"><a name="l00496"></a><span class="lineno">  496</span>&#160;    };</div><div class="line"><a name="l00497"></a><span class="lineno">  497</span>&#160;</div><div class="line"><a name="l00498"></a><span class="lineno">  498</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00499"></a><span class="lineno">  499</span>&#160;</div><div class="line"><a name="l00500"></a><span class="lineno">  500</span>&#160;<span class="preprocessor">#endif // OBOE_DEFINITIONS_H</span></div><div class="ttc" id="namespaceoboe_html_aedef0759ae3622b6f0324799bcbdebf0"><div class="ttname"><a href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">oboe::kNanosPerMicrosecond</a></div><div class="ttdeci">constexpr int64_t kNanosPerMicrosecond</div><div class="ttdef"><b>Definition:</b> Definitions.h:38</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright (C) 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_DEFINITIONS_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_DEFINITIONS_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &lt;type_traits&gt;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="comment">// Oboe needs to be able to build on old NDKs so we use hard coded constants.</span></div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="comment">// The correctness of these constants is verified in &quot;aaudio/AAudioLoader.cpp&quot;.</span></div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00032"></a><span class="lineno"><a class="line" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">   32</a></span>&#160;    constexpr int32_t <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a> = 0;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    <span class="comment">// TODO: Investigate using std::chrono</span></div><div class="line"><a name="l00038"></a><span class="lineno"><a class="line" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">   38</a></span>&#160;<span class="comment"></span>    constexpr int64_t <a class="code" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">kNanosPerMicrosecond</a> =    1000;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;</div><div class="line"><a name="l00043"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">   43</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a> =    <a class="code" href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">kNanosPerMicrosecond</a> * 1000;</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno"><a class="line" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">   48</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">kMillisPerSecond</a> =        1000;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;</div><div class="line"><a name="l00053"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5948466b593c4eab65f7025846a39f51">   53</a></span>&#160;    constexpr int64_t <a class="code" href="namespaceoboe.html#a5948466b593c4eab65f7025846a39f51">kNanosPerSecond</a> =         <a class="code" href="namespaceoboe.html#a831e887150474c087170679eaca8672b">kNanosPerMillisecond</a> * <a class="code" href="namespaceoboe.html#ad1bb9f5626cec20d3a052a8721959873">kMillisPerSecond</a>;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;</div><div class="line"><a name="l00058"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">   58</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a89fa2ce046723764618c29db737917f6">StreamState</a> : int32_t { <span class="comment">// aaudio_stream_state_t</span></div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;        Uninitialized = 0, <span class="comment">// AAUDIO_STREAM_STATE_UNINITIALIZED,</span></div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;        Unknown = 1, <span class="comment">// AAUDIO_STREAM_STATE_UNKNOWN,</span></div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;        Open = 2, <span class="comment">// AAUDIO_STREAM_STATE_OPEN,</span></div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;        Starting = 3, <span class="comment">// AAUDIO_STREAM_STATE_STARTING,</span></div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;        Started = 4, <span class="comment">// AAUDIO_STREAM_STATE_STARTED,</span></div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;        Pausing = 5, <span class="comment">// AAUDIO_STREAM_STATE_PAUSING,</span></div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;        Paused = 6, <span class="comment">// AAUDIO_STREAM_STATE_PAUSED,</span></div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;        Flushing = 7, <span class="comment">// AAUDIO_STREAM_STATE_FLUSHING,</span></div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;        Flushed = 8, <span class="comment">// AAUDIO_STREAM_STATE_FLUSHED,</span></div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;        Stopping = 9, <span class="comment">// AAUDIO_STREAM_STATE_STOPPING,</span></div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;        Stopped = 10, <span class="comment">// AAUDIO_STREAM_STATE_STOPPED,</span></div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;        Closing = 11, <span class="comment">// AAUDIO_STREAM_STATE_CLOSING,</span></div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;        Closed = 12, <span class="comment">// AAUDIO_STREAM_STATE_CLOSED,</span></div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;        Disconnected = 13, <span class="comment">// AAUDIO_STREAM_STATE_DISCONNECTED,</span></div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;    };</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00078"></a><span class="lineno"><a class="line" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">   78</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5ae">Direction</a> : int32_t { <span class="comment">// aaudio_direction_t</span></div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;        <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">Output</a> = 0, <span class="comment">// AAUDIO_DIRECTION_OUTPUT,</span></div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;        <a class="code" href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea324118a6721dd6b8a9b9f4e327df2bf5">Input</a> = 1, <span class="comment">// AAUDIO_DIRECTION_INPUT,</span></div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;    };</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00094"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">   94</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> : int32_t { <span class="comment">// aaudio_format_t</span></div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a4bbb8f967da6d1a610596d7257179c2b">Invalid</a> = -1, <span class="comment">// AAUDIO_FORMAT_INVALID,</span></div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;        <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = 0, <span class="comment">// AAUDIO_FORMAT_UNSPECIFIED,</span></div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6abcd774f891b5f9df7099f3ea75dadf8d">I16</a> = 1, <span class="comment">// AAUDIO_FORMAT_PCM_I16,</span></div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;        <a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6a22ae0e2b89e5e3d477f988cc36d3272b">Float</a> = 2, <span class="comment">// AAUDIO_FORMAT_PCM_FLOAT,</span></div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;    };</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00119"></a><span class="lineno"><a class="line" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">  119</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> : int32_t { <span class="comment">// aaudio_data_callback_result_t</span></div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;        <span class="comment">// Indicates to the caller that the callbacks should continue.</span></div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;        Continue = 0, <span class="comment">// AAUDIO_CALLBACK_RESULT_CONTINUE,</span></div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;        <span class="comment">// Indicates to the caller that the callbacks should stop immediately.</span></div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;        Stop = 1, <span class="comment">// AAUDIO_CALLBACK_RESULT_STOP,</span></div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;    };</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;</div><div class="line"><a name="l00131"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">  131</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> : int32_t { <span class="comment">// aaudio_result_t</span></div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;        OK = 0, <span class="comment">// AAUDIO_OK</span></div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;        ErrorBase = -900, <span class="comment">// AAUDIO_ERROR_BASE,</span></div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;        ErrorDisconnected = -899, <span class="comment">// AAUDIO_ERROR_DISCONNECTED,</span></div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;        ErrorIllegalArgument = -898, <span class="comment">// AAUDIO_ERROR_ILLEGAL_ARGUMENT,</span></div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;        ErrorInternal = -896, <span class="comment">// AAUDIO_ERROR_INTERNAL,</span></div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;        ErrorInvalidState = -895, <span class="comment">// AAUDIO_ERROR_INVALID_STATE,</span></div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;        ErrorInvalidHandle = -892, <span class="comment">// AAUDIO_ERROR_INVALID_HANDLE,</span></div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;        ErrorUnimplemented = -890, <span class="comment">// AAUDIO_ERROR_UNIMPLEMENTED,</span></div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;        ErrorUnavailable = -889, <span class="comment">// AAUDIO_ERROR_UNAVAILABLE,</span></div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;        ErrorNoFreeHandles = -888, <span class="comment">// AAUDIO_ERROR_NO_FREE_HANDLES,</span></div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;        ErrorNoMemory = -887, <span class="comment">// AAUDIO_ERROR_NO_MEMORY,</span></div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;        ErrorNull = -886, <span class="comment">// AAUDIO_ERROR_NULL,</span></div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;        ErrorTimeout = -885, <span class="comment">// AAUDIO_ERROR_TIMEOUT,</span></div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;        ErrorWouldBlock = -884, <span class="comment">// AAUDIO_ERROR_WOULD_BLOCK,</span></div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;        ErrorInvalidFormat = -883, <span class="comment">// AAUDIO_ERROR_INVALID_FORMAT,</span></div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;        ErrorOutOfRange = -882, <span class="comment">// AAUDIO_ERROR_OUT_OF_RANGE,</span></div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;        ErrorNoService = -881, <span class="comment">// AAUDIO_ERROR_NO_SERVICE,</span></div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;        ErrorInvalidRate = -880, <span class="comment">// AAUDIO_ERROR_INVALID_RATE,</span></div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;        <span class="comment">// Reserved for future AAudio result types</span></div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;        Reserved1,</div><div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;        Reserved2,</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;        Reserved3,</div><div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;        Reserved4,</div><div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;        Reserved5,</div><div class="line"><a name="l00156"></a><span class="lineno">  156</span>&#160;        Reserved6,</div><div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;        Reserved7,</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;        Reserved8,</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;        Reserved9,</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;        Reserved10,</div><div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;        ErrorClosed,</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;    };</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;</div><div class="line"><a name="l00167"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">  167</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520">SharingMode</a> : int32_t { <span class="comment">// aaudio_sharing_mode_t</span></div><div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;</div><div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;        <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520a2ef50b4c466304dc6ac77bac8a779971">Exclusive</a> = 0, <span class="comment">// AAUDIO_SHARING_MODE_EXCLUSIVE,</span></div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;        <a class="code" href="namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca">Shared</a> = 1, <span class="comment">// AAUDIO_SHARING_MODE_SHARED,</span></div><div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;    };</div><div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;</div><div class="line"><a name="l00192"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">  192</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184">PerformanceMode</a> : int32_t { <span class="comment">// aaudio_performance_mode_t</span></div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;        <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a> = 10, <span class="comment">// AAUDIO_PERFORMANCE_MODE_NONE,</span></div><div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;        <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184abbad080463ed11f9d77797c04aa1e5b1">PowerSaving</a> = 11, <span class="comment">// AAUDIO_PERFORMANCE_MODE_POWER_SAVING,</span></div><div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;        <a class="code" href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184a611907b5ab1865515c35357efa41a9b9">LowLatency</a> = 12, <span class="comment">// AAUDIO_PERFORMANCE_MODE_LOW_LATENCY</span></div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;    };</div><div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;</div><div class="line"><a name="l00213"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">  213</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">AudioApi</a> : int32_t {</div><div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;        <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>,</div><div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;</div><div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;        <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a24e758ea9c1e842ef71cc8ff8b63fa9b">OpenSLES</a>,</div><div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;</div><div class="line"><a name="l00227"></a><span class="lineno">  227</span>&#160;        <a class="code" href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">AAudio</a></div><div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;    };</div><div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;</div><div class="line"><a name="l00235"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">  235</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a> : int32_t {</div><div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;        <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a>,</div><div class="line"><a name="l00244"></a><span class="lineno">  244</span>&#160;        <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da90fd7fdf6f41406a75e5265b9583bb4e">Fastest</a>,</div><div class="line"><a name="l00245"></a><span class="lineno">  245</span>&#160;        Low,</div><div class="line"><a name="l00246"></a><span class="lineno">  246</span>&#160;        Medium,</div><div class="line"><a name="l00247"></a><span class="lineno">  247</span>&#160;        High,</div><div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;        <a class="code" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1da68ef004de6166492c1d668eb8efe09bd">Best</a>,</div><div class="line"><a name="l00252"></a><span class="lineno">  252</span>&#160;    };</div><div class="line"><a name="l00253"></a><span class="lineno">  253</span>&#160;</div><div class="line"><a name="l00263"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">  263</a></span>&#160;    <span class="keyword">enum class</span> <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a> : int32_t { <span class="comment">// aaudio_usage_t</span></div><div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">Media</a> =  1, <span class="comment">// AAUDIO_USAGE_MEDIA</span></div><div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;</div><div class="line"><a name="l00272"></a><span class="lineno">  272</span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">VoiceCommunication</a> = 2, <span class="comment">// AAUDIO_USAGE_VOICE_COMMUNICATION</span></div><div class="line"><a name="l00273"></a><span class="lineno">  273</span>&#160;</div><div class="line"><a name="l00277"></a><span class="lineno">  277</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a404f62633744bf4da0c6a27a2b78ce74">VoiceCommunicationSignalling</a> = 3, <span class="comment">// AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING</span></div><div class="line"><a name="l00278"></a><span class="lineno">  278</span>&#160;</div><div class="line"><a name="l00282"></a><span class="lineno">  282</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a46c4c4d980dfe025ae5b35aa0011dde4">Alarm</a> = 4, <span class="comment">// AAUDIO_USAGE_ALARM</span></div><div class="line"><a name="l00283"></a><span class="lineno">  283</span>&#160;</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a96d008db67fc0b5551a926842bbb6a71">Notification</a> = 5, <span class="comment">// AAUDIO_USAGE_NOTIFICATION</span></div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;</div><div class="line"><a name="l00293"></a><span class="lineno">  293</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a4e7a4b08274d472394b740a20d3bbdaf">NotificationRingtone</a> = 6, <span class="comment">// AAUDIO_USAGE_NOTIFICATION_RINGTONE</span></div><div class="line"><a name="l00294"></a><span class="lineno">  294</span>&#160;</div><div class="line"><a name="l00298"></a><span class="lineno">  298</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a089240b5380dbd12f1eac0ec258a3b2f">NotificationEvent</a> = 10, <span class="comment">// AAUDIO_USAGE_NOTIFICATION_EVENT</span></div><div class="line"><a name="l00299"></a><span class="lineno">  299</span>&#160;</div><div class="line"><a name="l00303"></a><span class="lineno">  303</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a639ffd54516c1a84a288a363c9469df8">AssistanceAccessibility</a> = 11, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY</span></div><div class="line"><a name="l00304"></a><span class="lineno">  304</span>&#160;</div><div class="line"><a name="l00308"></a><span class="lineno">  308</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0ade058a1314f9a8504593259ff4f21a1e">AssistanceNavigationGuidance</a> = 12, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE</span></div><div class="line"><a name="l00309"></a><span class="lineno">  309</span>&#160;</div><div class="line"><a name="l00313"></a><span class="lineno">  313</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a1ce57a0572748beebfc0c664ca1077e7">AssistanceSonification</a> = 13, <span class="comment">// AAUDIO_USAGE_ASSISTANCE_SONIFICATION</span></div><div class="line"><a name="l00314"></a><span class="lineno">  314</span>&#160;</div><div class="line"><a name="l00318"></a><span class="lineno">  318</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a63d72051e901c069f8aa1b32aa0c43bb">Game</a> = 14, <span class="comment">// AAUDIO_USAGE_GAME</span></div><div class="line"><a name="l00319"></a><span class="lineno">  319</span>&#160;</div><div class="line"><a name="l00323"></a><span class="lineno">  323</span>&#160;        <a class="code" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a9b1363da9503dbd4142c0274a88e8d4b">Assistant</a> = 16, <span class="comment">// AAUDIO_USAGE_ASSISTANT</span></div><div class="line"><a name="l00324"></a><span class="lineno">  324</span>&#160;    };</div><div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;</div><div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;</div><div class="line"><a name="l00339"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">  339</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a> : int32_t { <span class="comment">// aaudio_content_type_t</span></div><div class="line"><a name="l00340"></a><span class="lineno">  340</span>&#160;</div><div class="line"><a name="l00344"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba3dc48a4b4619aa4edd1da7b937b4dcd1">  344</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba3dc48a4b4619aa4edd1da7b937b4dcd1">Speech</a> = 1, <span class="comment">// AAUDIO_CONTENT_TYPE_SPEECH</span></div><div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;</div><div class="line"><a name="l00349"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604bac156fcc7b29059305cef26f3904d4517">  349</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604bac156fcc7b29059305cef26f3904d4517">Music</a> = 2, <span class="comment">// AAUDIO_CONTENT_TYPE_MUSIC</span></div><div class="line"><a name="l00350"></a><span class="lineno">  350</span>&#160;</div><div class="line"><a name="l00354"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba8b3b366178c2b7b1688bca6cd33758b1">  354</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba8b3b366178c2b7b1688bca6cd33758b1">Movie</a> = 3, <span class="comment">// AAUDIO_CONTENT_TYPE_MOVIE</span></div><div class="line"><a name="l00355"></a><span class="lineno">  355</span>&#160;</div><div class="line"><a name="l00360"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba0885eef555037e94a7cf39fe683c2799">  360</a></span>&#160;        <a class="code" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba0885eef555037e94a7cf39fe683c2799">Sonification</a> = 4, <span class="comment">// AAUDIO_CONTENT_TYPE_SONIFICATION</span></div><div class="line"><a name="l00361"></a><span class="lineno">  361</span>&#160;    };</div><div class="line"><a name="l00362"></a><span class="lineno">  362</span>&#160;</div><div class="line"><a name="l00372"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">  372</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06">InputPreset</a> : int32_t { <span class="comment">// aaudio_input_preset_t</span></div><div class="line"><a name="l00376"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">  376</a></span>&#160;<span class="comment"></span>        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">Generic</a> = 1, <span class="comment">// AAUDIO_INPUT_PRESET_GENERIC</span></div><div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;</div><div class="line"><a name="l00381"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a6e8ef178769235d18b44fe2bb5ab33fe">  381</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a6e8ef178769235d18b44fe2bb5ab33fe">Camcorder</a> = 5, <span class="comment">// AAUDIO_INPUT_PRESET_CAMCORDER</span></div><div class="line"><a name="l00382"></a><span class="lineno">  382</span>&#160;</div><div class="line"><a name="l00386"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc">  386</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc">VoiceRecognition</a> = 6, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_RECOGNITION</span></div><div class="line"><a name="l00387"></a><span class="lineno">  387</span>&#160;</div><div class="line"><a name="l00391"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">  391</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a1862e72c9730c448fbec6f61a5d8234d">VoiceCommunication</a> = 7, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION</span></div><div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;</div><div class="line"><a name="l00398"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06acad9424158aefae0af7975901b11d85f">  398</a></span>&#160;        <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06acad9424158aefae0af7975901b11d85f">Unprocessed</a> = 9, <span class="comment">// AAUDIO_INPUT_PRESET_UNPROCESSED</span></div><div class="line"><a name="l00399"></a><span class="lineno">  399</span>&#160;</div><div class="line"><a name="l00405"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06ad19edec0a23e435c774bf3bbcf1d999c">  405</a></span>&#160;         <a class="code" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06ad19edec0a23e435c774bf3bbcf1d999c">VoicePerformance</a> = 10, <span class="comment">// AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE</span></div><div class="line"><a name="l00406"></a><span class="lineno">  406</span>&#160;</div><div class="line"><a name="l00407"></a><span class="lineno">  407</span>&#160;    };</div><div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;</div><div class="line"><a name="l00414"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">  414</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf">SessionId</a> {</div><div class="line"><a name="l00420"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">  420</a></span>&#160;         <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">None</a> = -1, <span class="comment">// AAUDIO_SESSION_ID_NONE</span></div><div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;</div><div class="line"><a name="l00429"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123">  429</a></span>&#160;         <a class="code" href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123">Allocate</a> = 0, <span class="comment">// AAUDIO_SESSION_ID_ALLOCATE</span></div><div class="line"><a name="l00430"></a><span class="lineno">  430</span>&#160;    };</div><div class="line"><a name="l00431"></a><span class="lineno">  431</span>&#160;</div><div class="line"><a name="l00442"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029">  442</a></span>&#160;    <span class="keyword">enum</span> <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029">ChannelCount</a> : int32_t {</div><div class="line"><a name="l00446"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">  446</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a946257a568f77c12df4fc4c49125da76">Unspecified</a> = <a class="code" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a>,</div><div class="line"><a name="l00447"></a><span class="lineno">  447</span>&#160;</div><div class="line"><a name="l00451"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a8be103218645e121b51078620f452c79">  451</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a8be103218645e121b51078620f452c79">Mono</a> = 1,</div><div class="line"><a name="l00452"></a><span class="lineno">  452</span>&#160;</div><div class="line"><a name="l00456"></a><span class="lineno"><a class="line" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a534e646333ca7568317b171ea96b89ba">  456</a></span>&#160;      <a class="code" href="namespaceoboe.html#a522e6806948369987639a0d1df03c029a534e646333ca7568317b171ea96b89ba">Stereo</a> = 2,</div><div class="line"><a name="l00457"></a><span class="lineno">  457</span>&#160;    };</div><div class="line"><a name="l00458"></a><span class="lineno">  458</span>&#160;</div><div class="line"><a name="l00477"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html">  477</a></span>&#160;    <span class="keyword">class </span><a class="code" href="classoboe_1_1_default_stream_values.html">DefaultStreamValues</a> {</div><div class="line"><a name="l00478"></a><span class="lineno">  478</span>&#160;</div><div class="line"><a name="l00479"></a><span class="lineno">  479</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l00480"></a><span class="lineno">  480</span>&#160;</div><div class="line"><a name="l00482"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#a46a5d9a653f2153f618cadcab764e1b1">  482</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#a46a5d9a653f2153f618cadcab764e1b1">SampleRate</a>;</div><div class="line"><a name="l00484"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#ab5ea5576699cebc56193f5c297d3e300">  484</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#ab5ea5576699cebc56193f5c297d3e300">FramesPerBurst</a>;</div><div class="line"><a name="l00486"></a><span class="lineno"><a class="line" href="classoboe_1_1_default_stream_values.html#ad5dce538d5963c81bf58350ab730962d">  486</a></span>&#160;        <span class="keyword">static</span> int32_t <a class="code" href="classoboe_1_1_default_stream_values.html#ad5dce538d5963c81bf58350ab730962d">ChannelCount</a>;</div><div class="line"><a name="l00487"></a><span class="lineno">  487</span>&#160;</div><div class="line"><a name="l00488"></a><span class="lineno">  488</span>&#160;    };</div><div class="line"><a name="l00489"></a><span class="lineno">  489</span>&#160;</div><div class="line"><a name="l00493"></a><span class="lineno"><a class="line" href="structoboe_1_1_frame_timestamp.html">  493</a></span>&#160;    <span class="keyword">struct </span><a class="code" href="structoboe_1_1_frame_timestamp.html">FrameTimestamp</a> {</div><div class="line"><a name="l00494"></a><span class="lineno">  494</span>&#160;        int64_t position; <span class="comment">// in frames</span></div><div class="line"><a name="l00495"></a><span class="lineno">  495</span>&#160;        int64_t timestamp; <span class="comment">// in nanoseconds</span></div><div class="line"><a name="l00496"></a><span class="lineno">  496</span>&#160;    };</div><div class="line"><a name="l00497"></a><span class="lineno">  497</span>&#160;</div><div class="line"><a name="l00498"></a><span class="lineno"><a class="line" href="classoboe_1_1_oboe_globals.html">  498</a></span>&#160;    <span class="keyword">class </span><a class="code" href="classoboe_1_1_oboe_globals.html">OboeGlobals</a> {</div><div class="line"><a name="l00499"></a><span class="lineno">  499</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l00500"></a><span class="lineno">  500</span>&#160;</div><div class="line"><a name="l00501"></a><span class="lineno">  501</span>&#160;        <span class="keyword">static</span> <span class="keywordtype">bool</span> areWorkaroundsEnabled() {</div><div class="line"><a name="l00502"></a><span class="lineno">  502</span>&#160;            <span class="keywordflow">return</span> mWorkaroundsEnabled;</div><div class="line"><a name="l00503"></a><span class="lineno">  503</span>&#160;        }</div><div class="line"><a name="l00504"></a><span class="lineno">  504</span>&#160;</div><div class="line"><a name="l00510"></a><span class="lineno"><a class="line" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">  510</a></span>&#160;        <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">setWorkaroundsEnabled</a>(<span class="keywordtype">bool</span> enabled) {</div><div class="line"><a name="l00511"></a><span class="lineno">  511</span>&#160;            mWorkaroundsEnabled = enabled;</div><div class="line"><a name="l00512"></a><span class="lineno">  512</span>&#160;        }</div><div class="line"><a name="l00513"></a><span class="lineno">  513</span>&#160;</div><div class="line"><a name="l00514"></a><span class="lineno">  514</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l00515"></a><span class="lineno">  515</span>&#160;        <span class="keyword">static</span> <span class="keywordtype">bool</span> mWorkaroundsEnabled;</div><div class="line"><a name="l00516"></a><span class="lineno">  516</span>&#160;    };</div><div class="line"><a name="l00517"></a><span class="lineno">  517</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00518"></a><span class="lineno">  518</span>&#160;</div><div class="line"><a name="l00519"></a><span class="lineno">  519</span>&#160;<span class="preprocessor">#endif // OBOE_DEFINITIONS_H</span></div><div class="ttc" id="namespaceoboe_html_aedef0759ae3622b6f0324799bcbdebf0"><div class="ttname"><a href="namespaceoboe.html#aedef0759ae3622b6f0324799bcbdebf0">oboe::kNanosPerMicrosecond</a></div><div class="ttdeci">constexpr int64_t kNanosPerMicrosecond</div><div class="ttdef"><b>Definition:</b> Definitions.h:38</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a99780b1e8d754eb42abed0ca5253e55b">oboe::AudioApi::AAudio</a></div></div>
 <div class="ttc" id="namespaceoboe_html_af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54"><div class="ttname"><a href="namespaceoboe.html#af2147500089212955498a08ef2edb5aea29c2c02a361c9d7028472e5d92cd4a54">oboe::Direction::Output</a></div></div>
+<div class="ttc" id="classoboe_1_1_oboe_globals_html"><div class="ttname"><a href="classoboe_1_1_oboe_globals.html">oboe::OboeGlobals</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:498</div></div>
 <div class="ttc" id="namespaceoboe_html_a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123"><div class="ttname"><a href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa8485ca716c8cd4aafee372fd7028c123">oboe::Allocate</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:429</div></div>
 <div class="ttc" id="namespaceoboe_html_a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc"><div class="ttname"><a href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06af6e440b4e9edf49afe18aa4be77be6fc">oboe::VoiceRecognition</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:386</div></div>
 <div class="ttc" id="namespaceoboe_html_a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f"><div class="ttname"><a href="namespaceoboe.html#a5752250c10e96179e3618d7f72937eafa58c518b26e83ea48393a76f6c9ecb51f">oboe::None</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:420</div></div>
@@ -90,6 +91,7 @@
 <div class="ttc" id="namespaceoboe_html_a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544"><div class="ttname"><a href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">oboe::Generic</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:376</div></div>
 <div class="ttc" id="namespaceoboe_html_a1068781f3920654b1bfd7ed136468184a611907b5ab1865515c35357efa41a9b9"><div class="ttname"><a href="namespaceoboe.html#a1068781f3920654b1bfd7ed136468184a611907b5ab1865515c35357efa41a9b9">oboe::PerformanceMode::LowLatency</a></div></div>
 <div class="ttc" id="namespaceoboe_html_af85fc9910a287df6c5df0ed396bb75cd"><div class="ttname"><a href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">oboe::DataCallbackResult</a></div><div class="ttdeci">DataCallbackResult</div><div class="ttdef"><b>Definition:</b> Definitions.h:119</div></div>
+<div class="ttc" id="classoboe_1_1_oboe_globals_html_af2b8af764c5a5e6fc007b7725117303b"><div class="ttname"><a href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">oboe::OboeGlobals::setWorkaroundsEnabled</a></div><div class="ttdeci">static void setWorkaroundsEnabled(bool enabled)</div><div class="ttdef"><b>Definition:</b> Definitions.h:510</div></div>
 <div class="ttc" id="namespaceoboe_html_a92972414867c81d5974cb2ed7abefbf6"><div class="ttname"><a href="namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6">oboe::AudioApi</a></div><div class="ttdeci">AudioApi</div><div class="ttdef"><b>Definition:</b> Definitions.h:213</div></div>
 <div class="ttc" id="namespaceoboe_html_a2a3cec6f021c1a324df60273710c604b"><div class="ttname"><a href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">oboe::ContentType</a></div><div class="ttdeci">ContentType</div><div class="ttdef"><b>Definition:</b> Definitions.h:339</div></div>
 <div class="ttc" id="classoboe_1_1_default_stream_values_html"><div class="ttname"><a href="classoboe_1_1_default_stream_values.html">oboe::DefaultStreamValues</a></div><div class="ttdef"><b>Definition:</b> Definitions.h:477</div></div>
diff --git a/docs/reference/_latency_tuner_8h_source.html b/docs/reference/_latency_tuner_8h_source.html
index 1b827d7..c9481df 100644
--- a/docs/reference/_latency_tuner_8h_source.html
+++ b/docs/reference/_latency_tuner_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,13 +71,15 @@
 <div class="title">LatencyTuner.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2017 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_LATENCY_TUNER_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_LATENCY_TUNER_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStream.h&quot;</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00041"></a><span class="lineno"><a class="line" href="classoboe_1_1_latency_tuner.html">   41</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a> {</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">LatencyTuner</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> &amp;stream);</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;     <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">LatencyTuner</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> &amp;stream, int32_t maximumBufferSize);</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_latency_tuner.html#ad2be756965e6a9af3114008eda892174">tune</a>();</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">requestReset</a>();</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;     <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4">isAtMaximumBufferSize</a>();</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;    <span class="keywordtype">void</span> reset();</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;    <span class="keyword">enum class</span> State {</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;        Idle,</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;        Active,</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;        AtMax,</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;        Unsupported</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;    } ;</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;    <span class="comment">// arbitrary number of calls to wait before bumping up the latency</span></div><div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;    <span class="keyword">static</span> constexpr int32_t kIdleCount = 8;</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a>           &amp;mStream;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;    State                 mState = State::Idle;</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;    int32_t               mMaxBufferSize = 0;</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;    int32_t               mPreviousXRuns = 0;</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;    int32_t               mIdleCountDown = 0;</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;    std::atomic&lt;int32_t&gt;  mLatencyTriggerRequests{0}; <span class="comment">// TODO user atomic requester from AAudio</span></div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;    std::atomic&lt;int32_t&gt;  mLatencyTriggerResponses{0};</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;};</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;<span class="preprocessor">#endif // OBOE_LATENCY_TUNER_</span></div><div class="ttc" id="classoboe_1_1_latency_tuner_html_a6c0142e08dc65eda8f758b4794450867"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">oboe::LatencyTuner::requestReset</a></div><div class="ttdeci">void requestReset()</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2017 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_LATENCY_TUNER_</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_LATENCY_TUNER_</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;atomic&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStream.h&quot;</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00041"></a><span class="lineno"><a class="line" href="classoboe_1_1_latency_tuner.html">   41</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a> {</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">LatencyTuner</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> &amp;stream);</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">LatencyTuner</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> &amp;stream, int32_t maximumBufferSize);</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;    <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> <a class="code" href="classoboe_1_1_latency_tuner.html#ad2be756965e6a9af3114008eda892174">tune</a>();</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">requestReset</a>();</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;    <span class="keywordtype">bool</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4">isAtMaximumBufferSize</a>();</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;</div><div class="line"><a name="l00091"></a><span class="lineno"><a class="line" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">   91</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">setMinimumBufferSize</a>(int32_t bufferSize) {</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;        mMinimumBufferSize = bufferSize;</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;    }</div><div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;    int32_t getMinimumBufferSize()<span class="keyword"> const </span>{</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;        <span class="keywordflow">return</span> mMinimumBufferSize;</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;    }</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;</div><div class="line"><a name="l00108"></a><span class="lineno"><a class="line" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">  108</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">setBufferSizeIncrement</a>(int32_t sizeIncrement) {</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;        mBufferSizeIncrement = sizeIncrement;</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;    }</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;    int32_t getBufferSizeIncrement()<span class="keyword"> const </span>{</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;        <span class="keywordflow">return</span> mBufferSizeIncrement;</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;    }</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;</div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;    <span class="keywordtype">void</span> reset();</div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;    <span class="keyword">enum class</span> State {</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;        Idle,</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;        Active,</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;        AtMax,</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;        Unsupported</div><div class="line"><a name="l00131"></a><span class="lineno">  131</span>&#160;    } ;</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;    <span class="comment">// arbitrary number of calls to wait before bumping up the latency</span></div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;    <span class="keyword">static</span> constexpr int32_t kIdleCount = 8;</div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;    <span class="keyword">static</span> constexpr int32_t kDefaultNumBursts = 2;</div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;</div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;    AudioStream           &amp;mStream;</div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;    State                 mState = State::Idle;</div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;    int32_t               mMaxBufferSize = 0;</div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;    int32_t               mPreviousXRuns = 0;</div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;    int32_t               mIdleCountDown = 0;</div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;    int32_t               mMinimumBufferSize;</div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;    int32_t               mBufferSizeIncrement;</div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;    std::atomic&lt;int32_t&gt;  mLatencyTriggerRequests{0}; <span class="comment">// TODO user atomic requester from AAudio</span></div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;    std::atomic&lt;int32_t&gt;  mLatencyTriggerResponses{0};</div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;};</div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;<span class="preprocessor">#endif // OBOE_LATENCY_TUNER_</span></div><div class="ttc" id="classoboe_1_1_latency_tuner_html_a2684b30205126c8acd2f75d01cce05db"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">oboe::LatencyTuner::setBufferSizeIncrement</a></div><div class="ttdeci">void setBufferSizeIncrement(int32_t sizeIncrement)</div><div class="ttdef"><b>Definition:</b> LatencyTuner.h:108</div></div>
+<div class="ttc" id="classoboe_1_1_latency_tuner_html_a6c0142e08dc65eda8f758b4794450867"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">oboe::LatencyTuner::requestReset</a></div><div class="ttdeci">void requestReset()</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html"><div class="ttname"><a href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:44</div></div>
 <div class="ttc" id="classoboe_1_1_latency_tuner_html_a45c013fd6787ad09d328385d6314c4d4"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4">oboe::LatencyTuner::isAtMaximumBufferSize</a></div><div class="ttdeci">bool isAtMaximumBufferSize()</div></div>
 <div class="ttc" id="classoboe_1_1_latency_tuner_html_a0263b9a55825c0a403653b2b508073ea"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">oboe::LatencyTuner::LatencyTuner</a></div><div class="ttdeci">LatencyTuner(AudioStream &amp;stream)</div></div>
 <div class="ttc" id="classoboe_1_1_latency_tuner_html_ad2be756965e6a9af3114008eda892174"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#ad2be756965e6a9af3114008eda892174">oboe::LatencyTuner::tune</a></div><div class="ttdeci">Result tune()</div></div>
 <div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
 <div class="ttc" id="classoboe_1_1_latency_tuner_html"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></div><div class="ttdef"><b>Definition:</b> LatencyTuner.h:41</div></div>
+<div class="ttc" id="classoboe_1_1_latency_tuner_html_adc96aa53b18a051b6ccdacb838139bf8"><div class="ttname"><a href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">oboe::LatencyTuner::setMinimumBufferSize</a></div><div class="ttdeci">void setMinimumBufferSize(int32_t bufferSize)</div><div class="ttdef"><b>Definition:</b> LatencyTuner.h:91</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
diff --git a/docs/reference/_oboe_8h_source.html b/docs/reference/_oboe_8h_source.html
index 9228bbb..c808909 100644
--- a/docs/reference/_oboe_8h_source.html
+++ b/docs/reference/_oboe_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/_result_with_value_8h_source.html b/docs/reference/_result_with_value_8h_source.html
index 0325bb1..c4f798d 100644
--- a/docs/reference/_result_with_value_8h_source.html
+++ b/docs/reference/_result_with_value_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/_stabilized_callback_8h_source.html b/docs/reference/_stabilized_callback_8h_source.html
index 719a3b4..695cc28 100644
--- a/docs/reference/_stabilized_callback_8h_source.html
+++ b/docs/reference/_stabilized_callback_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,17 +71,17 @@
 <div class="title">StabilizedCallback.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2018 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STABILIZEDCALLBACK_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STABILIZEDCALLBACK_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStream.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html">   25</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> {</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *callback);</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;    <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a></div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;    <a class="code" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">onAudioReady</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <span class="keywordtype">void</span> *audioData, int32_t numFrames) <span class="keyword">override</span>;</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">   33</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">onErrorBeforeClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> error)<span class="keyword"> override </span>{</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;        <span class="keywordflow">return</span> mCallback-&gt;<a class="code" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">onErrorBeforeClose</a>(oboeStream, error);</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;    }</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00037"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">   37</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">onErrorAfterClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> error)<span class="keyword"> override </span>{</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;        <span class="comment">// Reset all fields now that the stream has been closed</span></div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;        mFrameCount = 0;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;        mEpochTimeNanos = 0;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;        mOpsPerNano = 1;</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;        <span class="keywordflow">return</span> mCallback-&gt;<a class="code" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">onErrorAfterClose</a>(oboeStream, error);</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;    }</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *mCallback = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    int64_t mFrameCount = 0;</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;    int64_t mEpochTimeNanos = 0;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;    <span class="keywordtype">double</span>  mOpsPerNano = 1;</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;    <span class="keywordtype">void</span> generateLoad(int64_t durationNanos);</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;};</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;<span class="preprocessor">#if defined(__i386__) || defined(__x86_64__)</span></div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;<span class="preprocessor">#define cpu_relax() asm volatile(&quot;rep; nop&quot; ::: &quot;memory&quot;);</span></div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;<span class="preprocessor">#elif defined(__arm__) || defined(__mips__)</span></div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;<span class="preprocessor">    #define cpu_relax() asm volatile(&quot;&quot;:::&quot;memory&quot;)</span></div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;<span class="preprocessor">#elif defined(__aarch64__)</span></div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;<span class="preprocessor">#define cpu_relax() asm volatile(&quot;yield&quot; ::: &quot;memory&quot;)</span></div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;<span class="preprocessor">#else</span></div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;<span class="preprocessor">#error &quot;cpu_relax is not defined for this architecture&quot;</span></div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;}</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;<span class="preprocessor">#endif //OBOE_STABILIZEDCALLBACK_H</span></div><div class="ttc" id="classoboe_1_1_stabilized_callback_html_ad447e12ebf732cf151655c1fbaf58a49"><div class="ttname"><a href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback::onAudioReady</a></div><div class="ttdeci">DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:33</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2018 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_STABILIZEDCALLBACK_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_STABILIZEDCALLBACK_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &quot;oboe/AudioStream.h&quot;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html">   25</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a> : <span class="keyword">public</span> <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> {</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="keyword">public</span>:</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;    <span class="keyword">explicit</span> <a class="code" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a>(<a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *callback);</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;    <a class="code" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a></div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;    <a class="code" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">onAudioReady</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <span class="keywordtype">void</span> *audioData, int32_t numFrames) <span class="keyword">override</span>;</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">   33</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">onErrorBeforeClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> error)<span class="keyword"> override </span>{</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;        <span class="keywordflow">return</span> mCallback-&gt;<a class="code" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a>(oboeStream, error);</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;    }</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00037"></a><span class="lineno"><a class="line" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">   37</a></span>&#160;    <span class="keywordtype">void</span> <a class="code" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">onErrorAfterClose</a>(<a class="code" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <a class="code" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> error)<span class="keyword"> override </span>{</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;        <span class="comment">// Reset all fields now that the stream has been closed</span></div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;        mFrameCount = 0;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;        mEpochTimeNanos = 0;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;        mOpsPerNano = 1;</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;        <span class="keywordflow">return</span> mCallback-&gt;<a class="code" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a>(oboeStream, error);</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;    }</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="keyword">private</span>:</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;    <a class="code" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *mCallback = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    int64_t mFrameCount = 0;</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;    int64_t mEpochTimeNanos = 0;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;    <span class="keywordtype">double</span>  mOpsPerNano = 1;</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;    <span class="keywordtype">void</span> generateLoad(int64_t durationNanos);</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;};</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;<span class="preprocessor">#if defined(__i386__) || defined(__x86_64__)</span></div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;<span class="preprocessor">#define cpu_relax() asm volatile(&quot;rep; nop&quot; ::: &quot;memory&quot;);</span></div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;<span class="preprocessor">#elif defined(__arm__) || defined(__mips__)</span></div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;<span class="preprocessor">    #define cpu_relax() asm volatile(&quot;&quot;:::&quot;memory&quot;)</span></div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;<span class="preprocessor">#elif defined(__aarch64__)</span></div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;<span class="preprocessor">#define cpu_relax() asm volatile(&quot;yield&quot; ::: &quot;memory&quot;)</span></div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;<span class="preprocessor">#else</span></div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;<span class="preprocessor">#error &quot;cpu_relax is not defined for this architecture&quot;</span></div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;}</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;<span class="preprocessor">#endif //OBOE_STABILIZEDCALLBACK_H</span></div><div class="ttc" id="classoboe_1_1_stabilized_callback_html_ad447e12ebf732cf151655c1fbaf58a49"><div class="ttname"><a href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback::onAudioReady</a></div><div class="ttdeci">DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_callback_html"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:181</div></div>
 <div class="ttc" id="namespaceoboe_html_af85fc9910a287df6c5df0ed396bb75cd"><div class="ttname"><a href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">oboe::DataCallbackResult</a></div><div class="ttdeci">DataCallbackResult</div><div class="ttdef"><b>Definition:</b> Definitions.h:119</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html_a76bd3ef3e00396e10c21812003654cfe"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">oboe::AudioStreamErrorCallback::onErrorAfterClose</a></div><div class="ttdeci">virtual void onErrorAfterClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:163</div></div>
 <div class="ttc" id="classoboe_1_1_audio_stream_html"><div class="ttname"><a href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:44</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html_a57a1b21efc764e8bbf8d92008a993bfd"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">oboe::AudioStreamCallback::onErrorAfterClose</a></div><div class="ttdeci">virtual void onErrorAfterClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:117</div></div>
-<div class="ttc" id="classoboe_1_1_audio_stream_callback_html_a77ceb641f941164d7b4d4c51c9a888b9"><div class="ttname"><a href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">oboe::AudioStreamCallback::onErrorBeforeClose</a></div><div class="ttdeci">virtual void onErrorBeforeClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:103</div></div>
 <div class="ttc" id="namespaceoboe_html_a486512e787b609c80ba4436f23929af1"><div class="ttname"><a href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a></div><div class="ttdeci">Result</div><div class="ttdef"><b>Definition:</b> Definitions.h:131</div></div>
 <div class="ttc" id="classoboe_1_1_stabilized_callback_html"><div class="ttname"><a href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></div><div class="ttdef"><b>Definition:</b> StabilizedCallback.h:25</div></div>
 <div class="ttc" id="namespaceoboe_html"><div class="ttname"><a href="namespaceoboe.html">oboe</a></div><div class="ttdef"><b>Definition:</b> AudioStream.h:31</div></div>
 <div class="ttc" id="classoboe_1_1_stabilized_callback_html_af7521da42c4b08a71e6102994f6f41f4"><div class="ttname"><a href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">oboe::StabilizedCallback::onErrorAfterClose</a></div><div class="ttdeci">void onErrorAfterClose(AudioStream *oboeStream, Result error) override</div><div class="ttdef"><b>Definition:</b> StabilizedCallback.h:37</div></div>
 <div class="ttc" id="classoboe_1_1_stabilized_callback_html_a7ec0e9fca3181962ab78716bcda83e10"><div class="ttname"><a href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">oboe::StabilizedCallback::onErrorBeforeClose</a></div><div class="ttdeci">void onErrorBeforeClose(AudioStream *oboeStream, Result error) override</div><div class="ttdef"><b>Definition:</b> StabilizedCallback.h:33</div></div>
+<div class="ttc" id="classoboe_1_1_audio_stream_error_callback_html_a4eb1e4916b71d8231e97b19898bc9bf0"><div class="ttname"><a href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">oboe::AudioStreamErrorCallback::onErrorBeforeClose</a></div><div class="ttdeci">virtual void onErrorBeforeClose(AudioStream *, Result)</div><div class="ttdef"><b>Definition:</b> AudioStreamCallback.h:147</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/_utilities_8h_source.html b/docs/reference/_utilities_8h_source.html
index 7ef55a7..3b508ae 100644
--- a/docs/reference/_utilities_8h_source.html
+++ b/docs/reference/_utilities_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,8 +71,10 @@
 <div class="title">Utilities.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_UTILITIES_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_UTILITIES_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;unistd.h&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;sys/types.h&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="keywordtype">void</span> <a class="code" href="namespaceoboe.html#adbda063116feb9fa98a31ee820170060">convertFloatToPcm16</a>(<span class="keyword">const</span> <span class="keywordtype">float</span> *source, int16_t *destination, int32_t numSamples);</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="keywordtype">void</span> <a class="code" href="namespaceoboe.html#ad17bee42828d13f2ef62a889e175c643">convertPcm16ToFloat</a>(<span class="keyword">const</span> int16_t *source, <span class="keywordtype">float</span> *destination, int32_t numSamples);</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;int32_t <a class="code" href="namespaceoboe.html#ac67383a3df0f6e7a51f8415ffd9fdaca">convertFormatToSizeInBytes</a>(<a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> format);</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> FromType&gt;</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">convertToText</a>(FromType input);</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;<span class="keywordtype">int</span> <a class="code" href="namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db">getSdkVersion</a>();</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;<span class="preprocessor">#endif //OBOE_UTILITIES_H</span></div><div class="ttc" id="namespaceoboe_html_adbda063116feb9fa98a31ee820170060"><div class="ttname"><a href="namespaceoboe.html#adbda063116feb9fa98a31ee820170060">oboe::convertFloatToPcm16</a></div><div class="ttdeci">void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples)</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2016 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_UTILITIES_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_UTILITIES_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;unistd.h&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="preprocessor">#include &lt;sys/types.h&gt;</span></div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="preprocessor">#include &lt;string&gt;</span></div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="preprocessor">#include &quot;oboe/Definitions.h&quot;</span></div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="keywordtype">void</span> <a class="code" href="namespaceoboe.html#adbda063116feb9fa98a31ee820170060">convertFloatToPcm16</a>(<span class="keyword">const</span> <span class="keywordtype">float</span> *source, int16_t *destination, int32_t numSamples);</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;<span class="keywordtype">void</span> <a class="code" href="namespaceoboe.html#ad17bee42828d13f2ef62a889e175c643">convertPcm16ToFloat</a>(<span class="keyword">const</span> int16_t *source, <span class="keywordtype">float</span> *destination, int32_t numSamples);</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;int32_t <a class="code" href="namespaceoboe.html#ac67383a3df0f6e7a51f8415ffd9fdaca">convertFormatToSizeInBytes</a>(<a class="code" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> format);</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> FromType&gt;</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">convertToText</a>(FromType input);</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;std::string <a class="code" href="namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b">getPropertyString</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * name);</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;<span class="keywordtype">int</span> <a class="code" href="namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5">getPropertyInteger</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * name, <span class="keywordtype">int</span> defaultValue);</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;<span class="keywordtype">int</span> <a class="code" href="namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db">getSdkVersion</a>();</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;<span class="preprocessor">#endif //OBOE_UTILITIES_H</span></div><div class="ttc" id="namespaceoboe_html_adbda063116feb9fa98a31ee820170060"><div class="ttname"><a href="namespaceoboe.html#adbda063116feb9fa98a31ee820170060">oboe::convertFloatToPcm16</a></div><div class="ttdeci">void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples)</div></div>
 <div class="ttc" id="namespaceoboe_html_af65aaea3c5d82eee6906664d61c094b3"><div class="ttname"><a href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">oboe::convertToText</a></div><div class="ttdeci">const char * convertToText(FromType input)</div></div>
+<div class="ttc" id="namespaceoboe_html_a1ff1f1323d722494dac353a6b4d1bd5b"><div class="ttname"><a href="namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b">oboe::getPropertyString</a></div><div class="ttdeci">std::string getPropertyString(const char *name)</div></div>
+<div class="ttc" id="namespaceoboe_html_a4284cffcf4d852ca4f357429303d7af5"><div class="ttname"><a href="namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5">oboe::getPropertyInteger</a></div><div class="ttdeci">int getPropertyInteger(const char *name, int defaultValue)</div></div>
 <div class="ttc" id="namespaceoboe_html_ad17bee42828d13f2ef62a889e175c643"><div class="ttname"><a href="namespaceoboe.html#ad17bee42828d13f2ef62a889e175c643">oboe::convertPcm16ToFloat</a></div><div class="ttdeci">void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples)</div></div>
 <div class="ttc" id="namespaceoboe_html_a92afc593e856571aacbfd02e57075df6"><div class="ttname"><a href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">oboe::AudioFormat</a></div><div class="ttdeci">AudioFormat</div><div class="ttdef"><b>Definition:</b> Definitions.h:94</div></div>
 <div class="ttc" id="namespaceoboe_html_ac67383a3df0f6e7a51f8415ffd9fdaca"><div class="ttname"><a href="namespaceoboe.html#ac67383a3df0f6e7a51f8415ffd9fdaca">oboe::convertFormatToSizeInBytes</a></div><div class="ttdeci">int32_t convertFormatToSizeInBytes(AudioFormat format)</div></div>
diff --git a/docs/reference/_version_8h_source.html b/docs/reference/_version_8h_source.html
index 0f4505b..db8a456 100644
--- a/docs/reference/_version_8h_source.html
+++ b/docs/reference/_version_8h_source.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,7 +71,7 @@
 <div class="title">Version.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2017 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_VERSIONINFO_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_VERSIONINFO_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="comment">// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description.</span></div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="preprocessor">#define OBOE_VERSION_MAJOR 1</span></div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;<span class="comment">// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description.</span></div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;<span class="preprocessor">#define OBOE_VERSION_MINOR 2</span></div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;<span class="comment">// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.</span></div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;<span class="preprocessor">#define OBOE_VERSION_PATCH 4</span></div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="preprocessor">#define OBOE_STRINGIFY(x) #x</span></div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;<span class="preprocessor">#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)</span></div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;<span class="comment">// Type: String literal. See below for description.</span></div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="preprocessor">#define OBOE_VERSION_TEXT \</span></div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_MAJOR) &quot;.&quot; \</span></div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_MINOR) &quot;.&quot; \</span></div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_PATCH)</span></div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;<span class="comment">// Type: 32-bit unsigned int. See below for description.</span></div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;<span class="preprocessor">#define OBOE_VERSION_NUMBER ((OBOE_VERSION_MAJOR &lt;&lt; 24) | (OBOE_VERSION_MINOR &lt;&lt; 16) | OBOE_VERSION_PATCH)</span></div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> * getVersionText();</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html">   61</a></span>&#160;<span class="keyword">struct </span><a class="code" href="structoboe_1_1_version.html">Version</a> {</div><div class="line"><a name="l00065"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a270f2e92582d5187be339eeda8e2b276">   65</a></span>&#160;    <span class="keyword">static</span> constexpr uint8_t <a class="code" href="structoboe_1_1_version.html#a270f2e92582d5187be339eeda8e2b276">Major</a> = OBOE_VERSION_MAJOR;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#ae460bb95e3a9099696205a35fffb5469">   71</a></span>&#160;    <span class="keyword">static</span> constexpr uint8_t <a class="code" href="structoboe_1_1_version.html#ae460bb95e3a9099696205a35fffb5469">Minor</a> = OBOE_VERSION_MINOR;</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a690110f2b3e887892da8f29ab5c057b2">   77</a></span>&#160;    <span class="keyword">static</span> constexpr uint16_t <a class="code" href="structoboe_1_1_version.html#a690110f2b3e887892da8f29ab5c057b2">Patch</a> = OBOE_VERSION_PATCH;</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00082"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a2c86e578b827fbca5f40c460a7754503">   82</a></span>&#160;    <span class="keyword">static</span> constexpr <span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="structoboe_1_1_version.html#a2c86e578b827fbca5f40c460a7754503">Text</a> = OBOE_VERSION_TEXT;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;</div><div class="line"><a name="l00088"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#ac579661e79bcee45dc676d4647891de0">   88</a></span>&#160;    <span class="keyword">static</span> constexpr uint32_t <a class="code" href="structoboe_1_1_version.html#ac579661e79bcee45dc676d4647891de0">Number</a> = OBOE_VERSION_NUMBER;</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;};</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;<span class="preprocessor">#endif //OBOE_VERSIONINFO_H</span></div><div class="ttc" id="structoboe_1_1_version_html"><div class="ttname"><a href="structoboe_1_1_version.html">oboe::Version</a></div><div class="ttdef"><b>Definition:</b> Version.h:61</div></div>
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"> * Copyright 2017 The Android Open Source Project</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> * You may obtain a copy of the License at</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> *      http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> *</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> * limitations under the License.</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> */</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="preprocessor">#ifndef OBOE_VERSIONINFO_H</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="preprocessor">#define OBOE_VERSIONINFO_H</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="comment">// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description.</span></div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="preprocessor">#define OBOE_VERSION_MAJOR 1</span></div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;<span class="comment">// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description.</span></div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;<span class="preprocessor">#define OBOE_VERSION_MINOR 5</span></div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;<span class="comment">// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.</span></div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;<span class="preprocessor">#define OBOE_VERSION_PATCH 0</span></div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="preprocessor">#define OBOE_STRINGIFY(x) #x</span></div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;<span class="preprocessor">#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)</span></div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;<span class="comment">// Type: String literal. See below for description.</span></div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="preprocessor">#define OBOE_VERSION_TEXT \</span></div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_MAJOR) &quot;.&quot; \</span></div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_MINOR) &quot;.&quot; \</span></div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;<span class="preprocessor">        OBOE_TOSTRING(OBOE_VERSION_PATCH)</span></div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;<span class="comment">// Type: 32-bit unsigned int. See below for description.</span></div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;<span class="preprocessor">#define OBOE_VERSION_NUMBER ((OBOE_VERSION_MAJOR &lt;&lt; 24) | (OBOE_VERSION_MINOR &lt;&lt; 16) | OBOE_VERSION_PATCH)</span></div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoboe.html">oboe</a> {</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> * getVersionText();</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html">   61</a></span>&#160;<span class="keyword">struct </span><a class="code" href="structoboe_1_1_version.html">Version</a> {</div><div class="line"><a name="l00065"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a270f2e92582d5187be339eeda8e2b276">   65</a></span>&#160;    <span class="keyword">static</span> constexpr uint8_t <a class="code" href="structoboe_1_1_version.html#a270f2e92582d5187be339eeda8e2b276">Major</a> = OBOE_VERSION_MAJOR;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#ae460bb95e3a9099696205a35fffb5469">   71</a></span>&#160;    <span class="keyword">static</span> constexpr uint8_t <a class="code" href="structoboe_1_1_version.html#ae460bb95e3a9099696205a35fffb5469">Minor</a> = OBOE_VERSION_MINOR;</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a690110f2b3e887892da8f29ab5c057b2">   77</a></span>&#160;    <span class="keyword">static</span> constexpr uint16_t <a class="code" href="structoboe_1_1_version.html#a690110f2b3e887892da8f29ab5c057b2">Patch</a> = OBOE_VERSION_PATCH;</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00082"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#a2c86e578b827fbca5f40c460a7754503">   82</a></span>&#160;    <span class="keyword">static</span> constexpr <span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="structoboe_1_1_version.html#a2c86e578b827fbca5f40c460a7754503">Text</a> = OBOE_VERSION_TEXT;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;</div><div class="line"><a name="l00088"></a><span class="lineno"><a class="line" href="structoboe_1_1_version.html#ac579661e79bcee45dc676d4647891de0">   88</a></span>&#160;    <span class="keyword">static</span> constexpr uint32_t <a class="code" href="structoboe_1_1_version.html#ac579661e79bcee45dc676d4647891de0">Number</a> = OBOE_VERSION_NUMBER;</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;};</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;} <span class="comment">// namespace oboe</span></div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;<span class="preprocessor">#endif //OBOE_VERSIONINFO_H</span></div><div class="ttc" id="structoboe_1_1_version_html"><div class="ttname"><a href="structoboe_1_1_version.html">oboe::Version</a></div><div class="ttdef"><b>Definition:</b> Version.h:61</div></div>
 <div class="ttc" id="structoboe_1_1_version_html_ae460bb95e3a9099696205a35fffb5469"><div class="ttname"><a href="structoboe_1_1_version.html#ae460bb95e3a9099696205a35fffb5469">oboe::Version::Minor</a></div><div class="ttdeci">static constexpr uint8_t Minor</div><div class="ttdef"><b>Definition:</b> Version.h:71</div></div>
 <div class="ttc" id="structoboe_1_1_version_html_a270f2e92582d5187be339eeda8e2b276"><div class="ttname"><a href="structoboe_1_1_version.html#a270f2e92582d5187be339eeda8e2b276">oboe::Version::Major</a></div><div class="ttdeci">static constexpr uint8_t Major</div><div class="ttdef"><b>Definition:</b> Version.h:65</div></div>
 <div class="ttc" id="structoboe_1_1_version_html_ac579661e79bcee45dc676d4647891de0"><div class="ttname"><a href="structoboe_1_1_version.html#ac579661e79bcee45dc676d4647891de0">oboe::Version::Number</a></div><div class="ttdeci">static constexpr uint32_t Number</div><div class="ttdef"><b>Definition:</b> Version.h:88</div></div>
diff --git a/docs/reference/annotated.html b/docs/reference/annotated.html
index 67027a4..2fdbca7 100644
--- a/docs/reference/annotated.html
+++ b/docs/reference/annotated.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -74,13 +74,16 @@
 <tr id="row_0_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_base.html" target="_self">AudioStreamBase</a></td><td class="desc"></td></tr>
 <tr id="row_0_2_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_builder.html" target="_self">AudioStreamBuilder</a></td><td class="desc"></td></tr>
 <tr id="row_0_3_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_callback.html" target="_self">AudioStreamCallback</a></td><td class="desc"></td></tr>
-<tr id="row_0_4_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_default_stream_values.html" target="_self">DefaultStreamValues</a></td><td class="desc"></td></tr>
-<tr id="row_0_5_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_frame_timestamp.html" target="_self">FrameTimestamp</a></td><td class="desc"></td></tr>
-<tr id="row_0_6_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_latency_tuner.html" target="_self">LatencyTuner</a></td><td class="desc"></td></tr>
-<tr id="row_0_7_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_result_with_value.html" target="_self">ResultWithValue</a></td><td class="desc"></td></tr>
-<tr id="row_0_8_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_stabilized_callback.html" target="_self">StabilizedCallback</a></td><td class="desc"></td></tr>
-<tr id="row_0_9_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_stream_deleter_functor.html" target="_self">StreamDeleterFunctor</a></td><td class="desc"></td></tr>
-<tr id="row_0_10_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_version.html" target="_self">Version</a></td><td class="desc"></td></tr>
+<tr id="row_0_4_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_data_callback.html" target="_self">AudioStreamDataCallback</a></td><td class="desc"></td></tr>
+<tr id="row_0_5_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_error_callback.html" target="_self">AudioStreamErrorCallback</a></td><td class="desc"></td></tr>
+<tr id="row_0_6_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_default_stream_values.html" target="_self">DefaultStreamValues</a></td><td class="desc"></td></tr>
+<tr id="row_0_7_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_frame_timestamp.html" target="_self">FrameTimestamp</a></td><td class="desc"></td></tr>
+<tr id="row_0_8_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_latency_tuner.html" target="_self">LatencyTuner</a></td><td class="desc"></td></tr>
+<tr id="row_0_9_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_oboe_globals.html" target="_self">OboeGlobals</a></td><td class="desc"></td></tr>
+<tr id="row_0_10_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_result_with_value.html" target="_self">ResultWithValue</a></td><td class="desc"></td></tr>
+<tr id="row_0_11_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_stabilized_callback.html" target="_self">StabilizedCallback</a></td><td class="desc"></td></tr>
+<tr id="row_0_12_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_stream_deleter_functor.html" target="_self">StreamDeleterFunctor</a></td><td class="desc"></td></tr>
+<tr id="row_0_13_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_version.html" target="_self">Version</a></td><td class="desc"></td></tr>
 </table>
 </div><!-- directory -->
 </div><!-- contents -->
diff --git a/docs/reference/classes.html b/docs/reference/classes.html
index 8ef7685..8209573 100644
--- a/docs/reference/classes.html
+++ b/docs/reference/classes.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -67,25 +67,27 @@
 <div class="title">Class Index</div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="qindex"><a class="qindex" href="#letter_a">a</a>&#160;|&#160;<a class="qindex" href="#letter_d">d</a>&#160;|&#160;<a class="qindex" href="#letter_f">f</a>&#160;|&#160;<a class="qindex" href="#letter_l">l</a>&#160;|&#160;<a class="qindex" href="#letter_r">r</a>&#160;|&#160;<a class="qindex" href="#letter_s">s</a>&#160;|&#160;<a class="qindex" href="#letter_v">v</a></div>
+<div class="qindex"><a class="qindex" href="#letter_a">a</a>&#160;|&#160;<a class="qindex" href="#letter_d">d</a>&#160;|&#160;<a class="qindex" href="#letter_f">f</a>&#160;|&#160;<a class="qindex" href="#letter_l">l</a>&#160;|&#160;<a class="qindex" href="#letter_o">o</a>&#160;|&#160;<a class="qindex" href="#letter_r">r</a>&#160;|&#160;<a class="qindex" href="#letter_s">s</a>&#160;|&#160;<a class="qindex" href="#letter_v">v</a></div>
 <table class="classindex">
 <tr><td rowspan="2" valign="bottom"><a name="letter_a"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;a&#160;&#160;</div></td></tr></table>
-</td><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_l"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;l&#160;&#160;</div></td></tr></table>
+</td><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_l"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;l&#160;&#160;</div></td></tr></table>
+</td><td rowspan="2" valign="bottom"><a name="letter_r"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;r&#160;&#160;</div></td></tr></table>
+</td><td valign="top"><a class="el" href="structoboe_1_1_stream_deleter_functor.html">StreamDeleterFunctor</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td></tr>
+<tr><td></td><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td></td><td rowspan="2" valign="bottom"><a name="letter_v"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;v&#160;&#160;</div></td></tr></table>
+</td></tr>
+<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_d"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;d&#160;&#160;</div></td></tr></table>
+</td><td valign="top"><a class="el" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td valign="top"><a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td></tr>
+<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td rowspan="2" valign="bottom"><a name="letter_o"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;o&#160;&#160;</div></td></tr></table>
 </td><td rowspan="2" valign="bottom"><a name="letter_s"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;s&#160;&#160;</div></td></tr></table>
-</td><td></td></tr>
-<tr><td></td><td rowspan="2" valign="bottom"><a name="letter_d"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;d&#160;&#160;</div></td></tr></table>
-</td><td></td><td></td><td></td></tr>
-<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td valign="top"><a class="el" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td valign="top"><a class="el" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td></tr>
-<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td valign="top"><a class="el" href="classoboe_1_1_default_stream_values.html">DefaultStreamValues</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_r"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;r&#160;&#160;</div></td></tr></table>
-</td><td valign="top"><a class="el" href="structoboe_1_1_stream_deleter_functor.html">StreamDeleterFunctor</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td></tr>
-<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_f"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;f&#160;&#160;</div></td></tr></table>
-</td><td></td><td rowspan="2" valign="bottom"><a name="letter_v"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;v&#160;&#160;</div></td></tr></table>
-</td><td></td></tr>
-<tr><td></td><td></td><td valign="top"><a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a class="el" href="structoboe_1_1_frame_timestamp.html">FrameTimestamp</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td valign="top"><a class="el" href="structoboe_1_1_version.html">Version</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td></tr>
+</td><td valign="top"><a class="el" href="structoboe_1_1_version.html">Version</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td></tr>
+<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td valign="top"><a class="el" href="classoboe_1_1_default_stream_values.html">DefaultStreamValues</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td></td><td></td></tr>
+<tr><td valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td rowspan="2" valign="bottom"><a name="letter_f"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;f&#160;&#160;</div></td></tr></table>
+</td><td valign="top"><a class="el" href="classoboe_1_1_oboe_globals.html">OboeGlobals</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td valign="top"><a class="el" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td></tr>
+<tr><td></td><td></td><td></td><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a class="el" href="structoboe_1_1_frame_timestamp.html">FrameTimestamp</a> (<a class="el" href="namespaceoboe.html">oboe</a>)&#160;&#160;&#160;</td><td></td><td></td><td></td></tr>
 <tr><td></td><td></td><td></td><td></td><td></td></tr>
 </table>
-<div class="qindex"><a class="qindex" href="#letter_a">a</a>&#160;|&#160;<a class="qindex" href="#letter_d">d</a>&#160;|&#160;<a class="qindex" href="#letter_f">f</a>&#160;|&#160;<a class="qindex" href="#letter_l">l</a>&#160;|&#160;<a class="qindex" href="#letter_r">r</a>&#160;|&#160;<a class="qindex" href="#letter_s">s</a>&#160;|&#160;<a class="qindex" href="#letter_v">v</a></div>
+<div class="qindex"><a class="qindex" href="#letter_a">a</a>&#160;|&#160;<a class="qindex" href="#letter_d">d</a>&#160;|&#160;<a class="qindex" href="#letter_f">f</a>&#160;|&#160;<a class="qindex" href="#letter_l">l</a>&#160;|&#160;<a class="qindex" href="#letter_o">o</a>&#160;|&#160;<a class="qindex" href="#letter_r">r</a>&#160;|&#160;<a class="qindex" href="#letter_s">s</a>&#160;|&#160;<a class="qindex" href="#letter_v">v</a></div>
 </div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/classoboe_1_1_audio_stream-members.html b/docs/reference/classoboe_1_1_audio_stream-members.html
index de1ff5d..b00cb36 100644
--- a/docs/reference/classoboe_1_1_audio_stream-members.html
+++ b/docs/reference/classoboe_1_1_audio_stream-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -78,27 +78,31 @@
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8ebb587a07bf62c864fd62c63b241fd4">AudioStream</a>(const AudioStreamBuilder &amp;builder)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">explicit</span></td></tr>
   <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>AudioStreamBase</b>() (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa6b103e1b0f808bbc4949d56f0829f98">AudioStreamBase</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">calculateLatencyMillis</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ab7a8cfe5d6039386bc5850fd5ee9bd62">fireDataCallback</a>(void *audioData, int numFrames)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a32c25c0333eab3d65ce02275ad4acb3d">flush</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() const =0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">getAvailableFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">getBytesPerFrame</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>AudioStreamBuilder</b> (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">friend</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ae023cb001f3261d064f423101798d6be">calculateLatencyMillis</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a9c8ea30e30e513766d5e996c370eb8d8">close</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ab7a8cfe5d6039386bc5850fd5ee9bd62">fireDataCallback</a>(void *audioData, int numFrames)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a32c25c0333eab3d65ce02275ad4acb3d">flush</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a2b7a3cee7444114843dbdd1fc705f6bb">getAudioApi</a>() const =0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">getAvailableFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc">getBytesPerFrame</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">getBytesPerSample</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a">getFramesPerBurst</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">getFramesRead</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341">getFramesWritten</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">getFramesRead</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341">getFramesWritten</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">getLastErrorCallbackResult</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">getPerformanceMode</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">getSampleRate</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">getSampleRateConversionQuality</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
@@ -112,55 +116,64 @@
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#ad1a1d3bbf3b348ed92b7ed18ce9cc261">getXRunCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">isChannelConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">isDataCallbackEnabled</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">isFormatConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">isXRunCountSupported</a>() const =0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aa5f4801cca6877eeaa4735b93933269d">launchStopThread</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">isXRunCountSupported</a>() const =0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aa5f4801cca6877eeaa4735b93933269d">launchStopThread</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>lockWeakThis</b>() (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr bgcolor="#f0f0f0"><td class="entry"><b>mChannelConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">mFramesRead</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">mFramesWritten</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>mLock</b> (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mErrorCallbackResult</b> (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">mFramesRead</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">mFramesWritten</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mLock</b> (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">onDefaultCallback</a>(void *, int)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">open</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a04f29836748a8e5842aef2be200022ad">pause</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">read</a>(void *, int32_t, int64_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a6bd5d633ff999e4da1faf3cd949aa602">requestFlush</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a7f18bb3cc5490fd7fbc1f6da63c730f6">requestPause</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a3c484e314dee8dfed1d419f487b5d601">requestStart</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a820e634f741e6b5efdcef8104cecb919">requestStop</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">setBufferSizeInFrames</a>(int32_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">setDataCallbackEnabled</a>(bool enabled)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>mWeakThis</b> (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">onDefaultCallback</a>(void *, int)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6">open</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a04f29836748a8e5842aef2be200022ad">pause</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8089f0a0cb68d4039cf33e6584129978">read</a>(void *, int32_t, int64_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a6bd5d633ff999e4da1faf3cd949aa602">requestFlush</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a7f18bb3cc5490fd7fbc1f6da63c730f6">requestPause</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a3c484e314dee8dfed1d419f487b5d601">requestStart</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a820e634f741e6b5efdcef8104cecb919">requestStop</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">setBufferSizeInFrames</a>(int32_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">setDataCallbackEnabled</a>(bool enabled)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>setWeakThis</b>(std::shared_ptr&lt; oboe::AudioStream &gt; &amp;sharedStream) (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">start</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aec093859d42f0470c884edd1e976d9f3">stop</a>(int64_t timeoutNanoseconds=kDefaultTimeoutNanos)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>swapCallback</b>(AudioStreamCallback *streamCallback) (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">updateFramesRead</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a64ad978c5f70ced17ef5a96605496515">updateFramesWritten</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">usesAAudio</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">waitForAvailableFrames</a>(int32_t numFrames, int64_t timeoutNanoseconds)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0c865a5501f369d959c39d8ab8b46a07">waitForStateChange</a>(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8adbacd6a55a94a532916ab037fba1d6">waitForStateTransition</a>(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">wasErrorCallbackCalled</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">write</a>(const void *, int32_t, int64_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStream</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamBase</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>swapDataCallback</b>(AudioStreamDataCallback *dataCallback) (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>swapErrorCallback</b>(AudioStreamErrorCallback *errorCallback) (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">updateFramesRead</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a64ad978c5f70ced17ef5a96605496515">updateFramesWritten</a>()=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a15cdaaaa4c1e8da322d6da33334c8147">usesAAudio</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">waitForAvailableFrames</a>(int32_t numFrames, int64_t timeoutNanoseconds)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a0c865a5501f369d959c39d8ab8b46a07">waitForStateChange</a>(StreamState inputState, StreamState *nextState, int64_t timeoutNanoseconds)=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a8adbacd6a55a94a532916ab037fba1d6">waitForStateTransition</a>(StreamState startingState, StreamState endingState, int64_t timeoutNanoseconds)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#aa48da7bf28026b7cccee73e6b054af28">wasErrorCallbackCalled</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html#a3612c05ed6b01a213dde67d913c07e11">write</a>(const void *, int32_t, int64_t)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStream</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamBase</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/classoboe_1_1_audio_stream.html b/docs/reference/classoboe_1_1_audio_stream.html
index 8130095..20c89c6 100644
--- a/docs/reference/classoboe_1_1_audio_stream.html
+++ b/docs/reference/classoboe_1_1_audio_stream.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -71,6 +71,7 @@
 <a href="#pub-methods">Public Member Functions</a> &#124;
 <a href="#pro-methods">Protected Member Functions</a> &#124;
 <a href="#pro-attribs">Protected Attributes</a> &#124;
+<a href="#friends">Friends</a> &#124;
 <a href="classoboe_1_1_audio_stream-members.html">List of all members</a>  </div>
   <div class="headertitle">
 <div class="title">oboe::AudioStream Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div>  </div>
@@ -154,13 +155,18 @@
 <tr class="separator:a64ad978c5f70ced17ef5a96605496515"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a462358ddab709c79d1a7968d6d55b727"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#a462358ddab709c79d1a7968d6d55b727">updateFramesRead</a> ()=0</td></tr>
 <tr class="separator:a462358ddab709c79d1a7968d6d55b727"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a20f75fce32d3a203404de0883c2de34f"><td class="memItemLeft" align="right" valign="top"><a id="a20f75fce32d3a203404de0883c2de34f"></a>
-<a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><b>swapCallback</b> (<a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *streamCallback)</td></tr>
-<tr class="separator:a20f75fce32d3a203404de0883c2de34f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ab1748ad90d9ff9210f0fee19cea71224"><td class="memItemLeft" align="right" valign="top"><a id="ab1748ad90d9ff9210f0fee19cea71224"></a>
+<a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><b>swapDataCallback</b> (<a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *dataCallback)</td></tr>
+<tr class="separator:ab1748ad90d9ff9210f0fee19cea71224"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aa75bb1b45bee873715a674df5dac0ef9"><td class="memItemLeft" align="right" valign="top"><a id="aa75bb1b45bee873715a674df5dac0ef9"></a>
+<a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><b>swapErrorCallback</b> (<a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *errorCallback)</td></tr>
+<tr class="separator:aa75bb1b45bee873715a674df5dac0ef9"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:afa35ee4b8629fbffe26b9be7c7ed55d2"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a>&lt; int32_t &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#afa35ee4b8629fbffe26b9be7c7ed55d2">getAvailableFrames</a> ()</td></tr>
 <tr class="separator:afa35ee4b8629fbffe26b9be7c7ed55d2"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:afddb0962863ccf9ec6672a042fe15941"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a>&lt; int32_t &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#afddb0962863ccf9ec6672a042fe15941">waitForAvailableFrames</a> (int32_t numFrames, int64_t timeoutNanoseconds)</td></tr>
 <tr class="separator:afddb0962863ccf9ec6672a042fe15941"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8fe8afdf164a1fe835c514f709743d75"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">getLastErrorCallbackResult</a> () const</td></tr>
+<tr class="separator:a8fe8afdf164a1fe835c514f709743d75"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="inherit_header pub_methods_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
 <tr class="memitem:aa6b103e1b0f808bbc4949d56f0829f98 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa6b103e1b0f808bbc4949d56f0829f98">AudioStreamBase</a> (const <a class="el" href="classoboe_1_1_audio_stream_base.html">AudioStreamBase</a> &amp;)=default</td></tr>
 <tr class="separator:aa6b103e1b0f808bbc4949d56f0829f98 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -174,6 +180,8 @@
 <tr class="separator:ae9d32f3e09174bad69e74f147ee33087 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a8878a90949badbb5486cc2e022a57086 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a> () const</td></tr>
 <tr class="separator:a8878a90949badbb5486cc2e022a57086 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:abc3ee2815568b425d15a40e132aa8e38 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a> () const</td></tr>
+<tr class="separator:abc3ee2815568b425d15a40e132aa8e38 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab1e640461d7bf9d596decb913da7ac86 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a> () const</td></tr>
 <tr class="separator:ab1e640461d7bf9d596decb913da7ac86 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:af5217ab05bfde0d7637024b599302d0b inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">virtual int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a> ()</td></tr>
@@ -186,8 +194,14 @@
 <tr class="separator:a2ddb935de0e24dd7ae8e2cfbecac9fdc inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a093057d625bc896864b959974c265f21 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a> () const</td></tr>
 <tr class="separator:a093057d625bc896864b959974c265f21 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a1b4a2a191546708da657510c3cd6b797 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a> () const</td></tr>
-<tr class="separator:a1b4a2a191546708da657510c3cd6b797 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9fb2f34ae62dbda2c10e8513b754fa0c inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a> () const</td></tr>
+<tr class="separator:a9fb2f34ae62dbda2c10e8513b754fa0c inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a1328fb9288166ff325995ce1ea1867f0 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a> () const</td></tr>
+<tr class="separator:a1328fb9288166ff325995ce1ea1867f0 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9a54d38b985a2eb12c6972104dc0ce73 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a> () const</td></tr>
+<tr class="separator:a9a54d38b985a2eb12c6972104dc0ce73 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aef579f6d1f779c89d051f0963f2976b3 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a> () const</td></tr>
+<tr class="separator:aef579f6d1f779c89d051f0963f2976b3 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a0bcfb2f8bd11c92b541fd910da9af397 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a> () const</td></tr>
 <tr class="separator:a0bcfb2f8bd11c92b541fd910da9af397 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab12e2d068fa87e0553b01a400d96eb82 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a> () const</td></tr>
@@ -217,9 +231,21 @@
 <tr class="separator:add85011ba825f74931deeb92c5edf831"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a0faa6d3a6fd4f367e6f80d5a29e6dcba"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">setDataCallbackEnabled</a> (bool enabled)</td></tr>
 <tr class="separator:a0faa6d3a6fd4f367e6f80d5a29e6dcba"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a68b28845855f7391c24ed0c7cee26ffe"><td class="memItemLeft" align="right" valign="top"><a id="a68b28845855f7391c24ed0c7cee26ffe"></a>
+void&#160;</td><td class="memItemRight" valign="bottom"><b>setWeakThis</b> (std::shared_ptr&lt; <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> &gt; &amp;sharedStream)</td></tr>
+<tr class="separator:a68b28845855f7391c24ed0c7cee26ffe"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a4882ba4180fa2a984fb9a2002651d50b"><td class="memItemLeft" align="right" valign="top"><a id="a4882ba4180fa2a984fb9a2002651d50b"></a>
+std::shared_ptr&lt; <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><b>lockWeakThis</b> ()</td></tr>
+<tr class="separator:a4882ba4180fa2a984fb9a2002651d50b"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header pro_methods_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pro_methods_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Protected Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
+<tr class="memitem:a5d5e07e98921d0193a5c0ccbe06f68c2 inherit pro_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a> ()</td></tr>
+<tr class="separator:a5d5e07e98921d0193a5c0ccbe06f68c2 inherit pro_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table><table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pro-attribs"></a>
 Protected Attributes</h2></td></tr>
+<tr class="memitem:addb945e8ab2bc395cc99c8ae6504c2cd"><td class="memItemLeft" align="right" valign="top"><a id="addb945e8ab2bc395cc99c8ae6504c2cd"></a>
+std::weak_ptr&lt; <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><b>mWeakThis</b></td></tr>
+<tr class="separator:addb945e8ab2bc395cc99c8ae6504c2cd"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a88a63317b7c58815bac074976b00aa23"><td class="memItemLeft" align="right" valign="top">std::atomic&lt; int64_t &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#a88a63317b7c58815bac074976b00aa23">mFramesWritten</a> {}</td></tr>
 <tr class="separator:a88a63317b7c58815bac074976b00aa23"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a07e82f9b9e2e4800f23ae9a7193c3b58"><td class="memItemLeft" align="right" valign="top">std::atomic&lt; int64_t &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream.html#a07e82f9b9e2e4800f23ae9a7193c3b58">mFramesRead</a> {}</td></tr>
@@ -227,9 +253,14 @@
 <tr class="memitem:ad23416968eb9479c300e4a94841bdde4"><td class="memItemLeft" align="right" valign="top"><a id="ad23416968eb9479c300e4a94841bdde4"></a>
 std::mutex&#160;</td><td class="memItemRight" valign="bottom"><b>mLock</b></td></tr>
 <tr class="separator:ad23416968eb9479c300e4a94841bdde4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:af4e4e04b87a53e6b286a6059be32b053"><td class="memItemLeft" align="right" valign="top"><a id="af4e4e04b87a53e6b286a6059be32b053"></a>
+<a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a>&#160;</td><td class="memItemRight" valign="bottom"><b>mErrorCallbackResult</b> = oboe::Result::OK</td></tr>
+<tr class="separator:af4e4e04b87a53e6b286a6059be32b053"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="inherit_header pro_attribs_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pro_attribs_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Protected Attributes inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
-<tr class="memitem:ae3f72318212dd9977d7fa0ced92c91f4 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = nullptr</td></tr>
-<tr class="separator:ae3f72318212dd9977d7fa0ced92c91f4 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6d8493f66a945cb426506c70f0358e5f inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = nullptr</td></tr>
+<tr class="separator:a6d8493f66a945cb426506c70f0358e5f inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:adc0c8cc54adb6d3350c62b8a74b9c57b inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = nullptr</td></tr>
+<tr class="separator:adc0c8cc54adb6d3350c62b8a74b9c57b inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a3962eb94420ad0ecea70029236001899 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
 <tr class="separator:a3962eb94420ad0ecea70029236001899 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a5ff460bac9d14dfeac4eeddfcbb6e206 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
@@ -269,6 +300,12 @@
 <tr class="memitem:a2dd35a6f009f36172838260144218f6d inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a id="a2dd35a6f009f36172838260144218f6d"></a>
 <a class="el" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a>&#160;</td><td class="memItemRight" valign="bottom"><b>mSampleRateConversionQuality</b> = SampleRateConversionQuality::None</td></tr>
 <tr class="separator:a2dd35a6f009f36172838260144218f6d inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="friends"></a>
+Friends</h2></td></tr>
+<tr class="memitem:a8468a51a2352c31aef00fade27a43e9e"><td class="memItemLeft" align="right" valign="top"><a id="a8468a51a2352c31aef00fade27a43e9e"></a>
+class&#160;</td><td class="memItemRight" valign="bottom"><b>AudioStreamBuilder</b></td></tr>
+<tr class="separator:a8468a51a2352c31aef00fade27a43e9e"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p>Base class for Oboe C++ audio stream. </p>
@@ -609,6 +646,32 @@
 
 </div>
 </div>
+<a id="a8fe8afdf164a1fe835c514f709743d75"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a8fe8afdf164a1fe835c514f709743d75">&#9670;&nbsp;</a></span>getLastErrorCallbackResult()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">oboe::Result</a> oboe::AudioStream::getLastErrorCallbackResult </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<dl class="section return"><dt>Returns</dt><dd>last result passed from an error callback </dd></dl>
+
+</div>
+</div>
 <a id="a9d37cc6513823c685ae892626ff83ea8"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a9d37cc6513823c685ae892626ff83ea8">&#9670;&nbsp;</a></span>getState()</h2>
 
diff --git a/docs/reference/classoboe_1_1_audio_stream_base-members.html b/docs/reference/classoboe_1_1_audio_stream_base-members.html
index e391c12..9fde259 100644
--- a/docs/reference/classoboe_1_1_audio_stream_base-members.html
+++ b/docs/reference/classoboe_1_1_audio_stream_base-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -78,13 +78,15 @@
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa6b103e1b0f808bbc4949d56f0829f98">AudioStreamBase</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">getPerformanceMode</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">getSampleRate</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
@@ -93,25 +95,29 @@
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1fb033fc963f971bd1aa8f6707e49b41">getSharingMode</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">isChannelConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">isFormatConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mChannelConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>mChannelConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
   <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamBase</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
diff --git a/docs/reference/classoboe_1_1_audio_stream_base.html b/docs/reference/classoboe_1_1_audio_stream_base.html
index 3c44656..093eb46 100644
--- a/docs/reference/classoboe_1_1_audio_stream_base.html
+++ b/docs/reference/classoboe_1_1_audio_stream_base.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -69,6 +69,7 @@
 <div class="header">
   <div class="summary">
 <a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pro-methods">Protected Member Functions</a> &#124;
 <a href="#pro-attribs">Protected Attributes</a> &#124;
 <a href="classoboe_1_1_audio_stream_base-members.html">List of all members</a>  </div>
   <div class="headertitle">
@@ -102,6 +103,8 @@
 <tr class="separator:ae9d32f3e09174bad69e74f147ee33087"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a8878a90949badbb5486cc2e022a57086"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a> () const</td></tr>
 <tr class="separator:a8878a90949badbb5486cc2e022a57086"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:abc3ee2815568b425d15a40e132aa8e38"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a> () const</td></tr>
+<tr class="separator:abc3ee2815568b425d15a40e132aa8e38"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab1e640461d7bf9d596decb913da7ac86"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a> () const</td></tr>
 <tr class="separator:ab1e640461d7bf9d596decb913da7ac86"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:af5217ab05bfde0d7637024b599302d0b"><td class="memItemLeft" align="right" valign="top">virtual int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a> ()</td></tr>
@@ -114,8 +117,14 @@
 <tr class="separator:a2ddb935de0e24dd7ae8e2cfbecac9fdc"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a093057d625bc896864b959974c265f21"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a> () const</td></tr>
 <tr class="separator:a093057d625bc896864b959974c265f21"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a1b4a2a191546708da657510c3cd6b797"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a> () const</td></tr>
-<tr class="separator:a1b4a2a191546708da657510c3cd6b797"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9fb2f34ae62dbda2c10e8513b754fa0c"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a> () const</td></tr>
+<tr class="separator:a9fb2f34ae62dbda2c10e8513b754fa0c"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a1328fb9288166ff325995ce1ea1867f0"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a> () const</td></tr>
+<tr class="separator:a1328fb9288166ff325995ce1ea1867f0"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9a54d38b985a2eb12c6972104dc0ce73"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a> () const</td></tr>
+<tr class="separator:a9a54d38b985a2eb12c6972104dc0ce73"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aef579f6d1f779c89d051f0963f2976b3"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a> () const</td></tr>
+<tr class="separator:aef579f6d1f779c89d051f0963f2976b3"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a0bcfb2f8bd11c92b541fd910da9af397"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a> () const</td></tr>
 <tr class="separator:a0bcfb2f8bd11c92b541fd910da9af397"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab12e2d068fa87e0553b01a400d96eb82"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a> () const</td></tr>
@@ -131,10 +140,17 @@
 <tr class="memitem:a1de8d6982d411a0cf50a32efba0ca3f2"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a82f3720eba7654aceb7282be36f9ff1d">SampleRateConversionQuality</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2">getSampleRateConversionQuality</a> () const</td></tr>
 <tr class="separator:a1de8d6982d411a0cf50a32efba0ca3f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pro-methods"></a>
+Protected Member Functions</h2></td></tr>
+<tr class="memitem:a5d5e07e98921d0193a5c0ccbe06f68c2"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a> ()</td></tr>
+<tr class="separator:a5d5e07e98921d0193a5c0ccbe06f68c2"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pro-attribs"></a>
 Protected Attributes</h2></td></tr>
-<tr class="memitem:ae3f72318212dd9977d7fa0ced92c91f4"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = nullptr</td></tr>
-<tr class="separator:ae3f72318212dd9977d7fa0ced92c91f4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6d8493f66a945cb426506c70f0358e5f"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = nullptr</td></tr>
+<tr class="separator:a6d8493f66a945cb426506c70f0358e5f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:adc0c8cc54adb6d3350c62b8a74b9c57b"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = nullptr</td></tr>
+<tr class="separator:adc0c8cc54adb6d3350c62b8a74b9c57b"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a3962eb94420ad0ecea70029236001899"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
 <tr class="separator:a3962eb94420ad0ecea70029236001899"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a5ff460bac9d14dfeac4eeddfcbb6e206"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
@@ -259,32 +275,6 @@
 
 </div>
 </div>
-<a id="a1b4a2a191546708da657510c3cd6b797"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a1b4a2a191546708da657510c3cd6b797">&#9670;&nbsp;</a></span>getCallback()</h2>
-
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>* oboe::AudioStreamBase::getCallback </td>
-          <td>(</td>
-          <td class="paramname"></td><td>)</td>
-          <td> const</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-<dl class="section return"><dt>Returns</dt><dd>the callback object for this stream, if set. </dd></dl>
-
-</div>
-</div>
 <a id="a87e6bf37d6a2a5e983b8ca8d29aea575"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a87e6bf37d6a2a5e983b8ca8d29aea575">&#9670;&nbsp;</a></span>getChannelCount()</h2>
 
@@ -337,6 +327,32 @@
 
 </div>
 </div>
+<a id="a9fb2f34ae62dbda2c10e8513b754fa0c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a9fb2f34ae62dbda2c10e8513b754fa0c">&#9670;&nbsp;</a></span>getDataCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a>* oboe::AudioStreamBase::getDataCallback </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>For internal use only. </p><dl class="section return"><dt>Returns</dt><dd>the data callback object for this stream, if set. </dd></dl>
+
+</div>
+</div>
 <a id="a093057d625bc896864b959974c265f21"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a093057d625bc896864b959974c265f21">&#9670;&nbsp;</a></span>getDeviceId()</h2>
 
@@ -389,6 +405,32 @@
 
 </div>
 </div>
+<a id="a1328fb9288166ff325995ce1ea1867f0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a1328fb9288166ff325995ce1ea1867f0">&#9670;&nbsp;</a></span>getErrorCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a>* oboe::AudioStreamBase::getErrorCallback </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>For internal use only. </p><dl class="section return"><dt>Returns</dt><dd>the error callback object for this stream, if set. </dd></dl>
+
+</div>
+</div>
 <a id="ab1e640461d7bf9d596decb913da7ac86"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#ab1e640461d7bf9d596decb913da7ac86">&#9670;&nbsp;</a></span>getFormat()</h2>
 
@@ -437,7 +479,33 @@
   </tr>
 </table>
 </div><div class="memdoc">
-<dl class="section return"><dt>Returns</dt><dd>the number of frames in each callback or kUnspecified. </dd></dl>
+<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000002">Deprecated:</a></b></dt><dd>use <code>getFramesPerDataCallback</code> instead. </dd></dl>
+
+</div>
+</div>
+<a id="abc3ee2815568b425d15a40e132aa8e38"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#abc3ee2815568b425d15a40e132aa8e38">&#9670;&nbsp;</a></span>getFramesPerDataCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">int32_t oboe::AudioStreamBase::getFramesPerDataCallback </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<dl class="section return"><dt>Returns</dt><dd>the number of frames in each data callback or kUnspecified. </dd></dl>
 
 </div>
 </div>
@@ -649,6 +717,58 @@
 
 </div>
 </div>
+<a id="a9a54d38b985a2eb12c6972104dc0ce73"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a9a54d38b985a2eb12c6972104dc0ce73">&#9670;&nbsp;</a></span>isDataCallbackSpecified()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool oboe::AudioStreamBase::isDataCallbackSpecified </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<dl class="section return"><dt>Returns</dt><dd>true if a data callback was set for this stream </dd></dl>
+
+</div>
+</div>
+<a id="aef579f6d1f779c89d051f0963f2976b3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#aef579f6d1f779c89d051f0963f2976b3">&#9670;&nbsp;</a></span>isErrorCallbackSpecified()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool oboe::AudioStreamBase::isErrorCallbackSpecified </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td> const</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Note that if the app does not set an error callback then a default one may be provided. </p><dl class="section return"><dt>Returns</dt><dd>true if an error callback was set for this stream </dd></dl>
+
+</div>
+</div>
 <a id="ace3625a7332bf02a86818fdf63fcccb4"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#ace3625a7332bf02a86818fdf63fcccb4">&#9670;&nbsp;</a></span>isFormatConversionAllowed()</h2>
 
@@ -675,6 +795,32 @@
 
 </div>
 </div>
+<a id="a5d5e07e98921d0193a5c0ccbe06f68c2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a5d5e07e98921d0193a5c0ccbe06f68c2">&#9670;&nbsp;</a></span>isValidConfig()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> oboe::AudioStreamBase::isValidConfig </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Validate stream parameters that might not be checked in lower layers </p>
+
+</div>
+</div>
 <a id="aa9c987a59555d7a60b9f7a63f4afc7fc"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#aa9c987a59555d7a60b9f7a63f4afc7fc">&#9670;&nbsp;</a></span>operator=()</h2>
 
@@ -795,6 +941,29 @@
 
 </div>
 </div>
+<a id="a6d8493f66a945cb426506c70f0358e5f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a6d8493f66a945cb426506c70f0358e5f">&#9670;&nbsp;</a></span>mDataCallback</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a>* oboe::AudioStreamBase::mDataCallback = nullptr</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>The callback which will be fired when new data is ready to be read/written. </p>
+
+</div>
+</div>
 <a id="a23dafa12fb1a6242b088ebd5a52798c8"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a23dafa12fb1a6242b088ebd5a52798c8">&#9670;&nbsp;</a></span>mDeviceId</h2>
 
@@ -841,6 +1010,29 @@
 
 </div>
 </div>
+<a id="adc0c8cc54adb6d3350c62b8a74b9c57b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#adc0c8cc54adb6d3350c62b8a74b9c57b">&#9670;&nbsp;</a></span>mErrorCallback</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a>* oboe::AudioStreamBase::mErrorCallback = nullptr</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>The callback which will be fired when an error or a disconnect occurs. </p>
+
+</div>
+</div>
 <a id="a7869f04836c2c2bdc10c7309ad4b8e09"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a7869f04836c2c2bdc10c7309ad4b8e09">&#9670;&nbsp;</a></span>mFormat</h2>
 
@@ -1025,29 +1217,6 @@
 
 </div>
 </div>
-<a id="ae3f72318212dd9977d7fa0ced92c91f4"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#ae3f72318212dd9977d7fa0ced92c91f4">&#9670;&nbsp;</a></span>mStreamCallback</h2>
-
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a>* oboe::AudioStreamBase::mStreamCallback = nullptr</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">protected</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-<p>The callback which will be fired when new data is ready to be read/written </p>
-
-</div>
-</div>
 <a id="a5b518e82f39c9fcbd7050fd66adb253c"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a5b518e82f39c9fcbd7050fd66adb253c">&#9670;&nbsp;</a></span>mUsage</h2>
 
diff --git a/docs/reference/classoboe_1_1_audio_stream_builder-members.html b/docs/reference/classoboe_1_1_audio_stream_builder-members.html
index a704f6f..8356cd9 100644
--- a/docs/reference/classoboe_1_1_audio_stream_builder-members.html
+++ b/docs/reference/classoboe_1_1_audio_stream_builder-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -81,13 +81,15 @@
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#ac9d41811c297fd28bc61833f640bb8d0">getAudioApi</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1531253e64aaebe9e9eddbafb9098fc">getBufferCapacityInFrames</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">getChannelCount</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">getDirection</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">getInputPreset</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">getPerformanceMode</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087">getSampleRate</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
@@ -98,40 +100,48 @@
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a622732bbe5c6577356d749f7dc2108df">isAAudioRecommended</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a18e7b5f7554a4c2ca763e35e8117d699">isAAudioSupported</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495">isChannelConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">isFormatConversionAllowed</a>() const</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>mChannelConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ac81d4719b350f8138aad1af38f0873b6">mBufferCapacityInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a">mBufferSizeInFrames</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mChannelConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">mContentType</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">mDeviceId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">mDirection</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">mFormat</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mFormatConversionAllowed</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e">mFramesPerBurst</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1e5d4f5b30c4cc36f81ffd858cc00589">mInputPreset</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab99671c2d0552557e75dc7b4afe91765">mPerformanceMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea">mSampleRate</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>mSampleRateConversionQuality</b> (defined in <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737">mSessionId</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">mSharingMode</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">mUsage</a></td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff">openManagedStream</a>(ManagedStream &amp;stream)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">openStream</a>(AudioStream **stream)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">setAudioApi</a>(AudioApi audioApi)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">setBufferCapacityInFrames</a>(int32_t bufferCapacityInFrames)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">setCallback</a>(AudioStreamCallback *streamCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">setChannelConversionAllowed</a>(bool allowed)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">setChannelCount</a>(int channelCount)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">setContentType</a>(ContentType contentType)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb">openStream</a>(std::shared_ptr&lt; oboe::AudioStream &gt; &amp;stream)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html#aa9c987a59555d7a60b9f7a63f4afc7fc">operator=</a>(const AudioStreamBase &amp;)=default</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391">setAudioApi</a>(AudioApi audioApi)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">setBufferCapacityInFrames</a>(int32_t bufferCapacityInFrames)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">setCallback</a>(AudioStreamCallback *streamCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">setChannelConversionAllowed</a>(bool allowed)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7">setChannelCount</a>(int channelCount)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">setContentType</a>(ContentType contentType)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">setDataCallback</a>(oboe::AudioStreamDataCallback *dataCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">setDeviceId</a>(int32_t deviceId)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">setDirection</a>(Direction direction)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">setFormat</a>(AudioFormat format)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">setFormatConversionAllowed</a>(bool allowed)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">setFramesPerCallback</a>(int framesPerCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">setErrorCallback</a>(oboe::AudioStreamErrorCallback *errorCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">setFormat</a>(AudioFormat format)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2">setFormatConversionAllowed</a>(bool allowed)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">setFramesPerCallback</a>(int framesPerCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">setFramesPerDataCallback</a>(int framesPerCallback)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">setInputPreset</a>(InputPreset inputPreset)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">setPerformanceMode</a>(PerformanceMode performanceMode)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d">setSampleRate</a>(int32_t sampleRate)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_builder.html">oboe::AudioStreamBuilder</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
diff --git a/docs/reference/classoboe_1_1_audio_stream_builder.html b/docs/reference/classoboe_1_1_audio_stream_builder.html
index afd1e1b..78c1e16 100644
--- a/docs/reference/classoboe_1_1_audio_stream_builder.html
+++ b/docs/reference/classoboe_1_1_audio_stream_builder.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -100,6 +100,8 @@
 <tr class="separator:a30ef3d5f51d56a9f980dc09600ed139d"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a3f397821f61eabaeedaf31064c859a54"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">setFramesPerCallback</a> (int framesPerCallback)</td></tr>
 <tr class="separator:a3f397821f61eabaeedaf31064c859a54"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:afb8e95e80df7edd1af27af490438785e"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">setFramesPerDataCallback</a> (int framesPerCallback)</td></tr>
+<tr class="separator:afb8e95e80df7edd1af27af490438785e"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:aa2e1d2d73cd6c2eb9f349bf2fe5f6515"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">setFormat</a> (<a class="el" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a> format)</td></tr>
 <tr class="separator:aa2e1d2d73cd6c2eb9f349bf2fe5f6515"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:abaff480867af51ca0899bfa6fd7cc3ef"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">setBufferCapacityInFrames</a> (int32_t bufferCapacityInFrames)</td></tr>
@@ -122,6 +124,10 @@
 <tr class="separator:a54c1651bdbe089d0d714af499e8a5f1d"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:af36ddcd00686a9e1de661bdac0685a8e"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e">setDeviceId</a> (int32_t deviceId)</td></tr>
 <tr class="separator:af36ddcd00686a9e1de661bdac0685a8e"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:acad307720e0f370267b4e2f9a626ae70"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">setDataCallback</a> (<a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a> *dataCallback)</td></tr>
+<tr class="separator:acad307720e0f370267b4e2f9a626ae70"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aacb66f530bfc6f545911b5e169774567"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">setErrorCallback</a> (<a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a> *errorCallback)</td></tr>
+<tr class="separator:aacb66f530bfc6f545911b5e169774567"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a698cefa9af73bc97c020c004821fccbd"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">setCallback</a> (<a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *streamCallback)</td></tr>
 <tr class="separator:a698cefa9af73bc97c020c004821fccbd"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ad50f5d20cdf420d982bf499790cd3563"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563">setChannelConversionAllowed</a> (bool allowed)</td></tr>
@@ -134,6 +140,8 @@
 <tr class="separator:aa07ea100fcb107d9f7913f206c2214f4"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a86b94cfa47729bef2e04dce1a9086074"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">openStream</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> **stream)</td></tr>
 <tr class="separator:a86b94cfa47729bef2e04dce1a9086074"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a44b68216c48f8fb08a9e63178e0b0eeb"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb">openStream</a> (std::shared_ptr&lt; <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> &gt; &amp;stream)</td></tr>
+<tr class="separator:a44b68216c48f8fb08a9e63178e0b0eeb"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a7ab172a9be4fca2489aa5cbcc48c20ff"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff">openManagedStream</a> (ManagedStream &amp;stream)</td></tr>
 <tr class="separator:a7ab172a9be4fca2489aa5cbcc48c20ff"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="inherit_header pub_methods_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
@@ -149,6 +157,8 @@
 <tr class="separator:ae9d32f3e09174bad69e74f147ee33087 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a8878a90949badbb5486cc2e022a57086 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">getFramesPerCallback</a> () const</td></tr>
 <tr class="separator:a8878a90949badbb5486cc2e022a57086 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:abc3ee2815568b425d15a40e132aa8e38 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">getFramesPerDataCallback</a> () const</td></tr>
+<tr class="separator:abc3ee2815568b425d15a40e132aa8e38 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab1e640461d7bf9d596decb913da7ac86 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a92afc593e856571aacbfd02e57075df6">AudioFormat</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">getFormat</a> () const</td></tr>
 <tr class="separator:ab1e640461d7bf9d596decb913da7ac86 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:af5217ab05bfde0d7637024b599302d0b inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">virtual int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b">getBufferSizeInFrames</a> ()</td></tr>
@@ -161,8 +171,14 @@
 <tr class="separator:a2ddb935de0e24dd7ae8e2cfbecac9fdc inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a093057d625bc896864b959974c265f21 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">getDeviceId</a> () const</td></tr>
 <tr class="separator:a093057d625bc896864b959974c265f21 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a1b4a2a191546708da657510c3cd6b797 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">getCallback</a> () const</td></tr>
-<tr class="separator:a1b4a2a191546708da657510c3cd6b797 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9fb2f34ae62dbda2c10e8513b754fa0c inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">getDataCallback</a> () const</td></tr>
+<tr class="separator:a9fb2f34ae62dbda2c10e8513b754fa0c inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a1328fb9288166ff325995ce1ea1867f0 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">getErrorCallback</a> () const</td></tr>
+<tr class="separator:a1328fb9288166ff325995ce1ea1867f0 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a9a54d38b985a2eb12c6972104dc0ce73 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">isDataCallbackSpecified</a> () const</td></tr>
+<tr class="separator:a9a54d38b985a2eb12c6972104dc0ce73 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aef579f6d1f779c89d051f0963f2976b3 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">isErrorCallbackSpecified</a> () const</td></tr>
+<tr class="separator:aef579f6d1f779c89d051f0963f2976b3 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a0bcfb2f8bd11c92b541fd910da9af397 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0">Usage</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a0bcfb2f8bd11c92b541fd910da9af397">getUsage</a> () const</td></tr>
 <tr class="separator:a0bcfb2f8bd11c92b541fd910da9af397 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:ab12e2d068fa87e0553b01a400d96eb82 inherit pub_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceoboe.html#a2a3cec6f021c1a324df60273710c604b">ContentType</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">getContentType</a> () const</td></tr>
@@ -187,9 +203,14 @@
 </table><table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="inherited"></a>
 Additional Inherited Members</h2></td></tr>
+<tr class="inherit_header pro_methods_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pro_methods_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Protected Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
+<tr class="memitem:a5d5e07e98921d0193a5c0ccbe06f68c2 inherit pro_methods_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">isValidConfig</a> ()</td></tr>
+<tr class="separator:a5d5e07e98921d0193a5c0ccbe06f68c2 inherit pro_methods_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="inherit_header pro_attribs_classoboe_1_1_audio_stream_base"><td colspan="2" onclick="javascript:toggleInherit('pro_attribs_classoboe_1_1_audio_stream_base')"><img src="closed.png" alt="-"/>&#160;Protected Attributes inherited from <a class="el" href="classoboe_1_1_audio_stream_base.html">oboe::AudioStreamBase</a></td></tr>
-<tr class="memitem:ae3f72318212dd9977d7fa0ced92c91f4 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">mStreamCallback</a> = nullptr</td></tr>
-<tr class="separator:ae3f72318212dd9977d7fa0ced92c91f4 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6d8493f66a945cb426506c70f0358e5f inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">mDataCallback</a> = nullptr</td></tr>
+<tr class="separator:a6d8493f66a945cb426506c70f0358e5f inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:adc0c8cc54adb6d3350c62b8a74b9c57b inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">mErrorCallback</a> = nullptr</td></tr>
+<tr class="separator:adc0c8cc54adb6d3350c62b8a74b9c57b inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a3962eb94420ad0ecea70029236001899 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899">mFramesPerCallback</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
 <tr class="separator:a3962eb94420ad0ecea70029236001899 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a5ff460bac9d14dfeac4eeddfcbb6e206 inherit pro_attribs_classoboe_1_1_audio_stream_base"><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206">mChannelCount</a> = <a class="el" href="namespaceoboe.html#ab0772052200184e514082eaa89be7905">kUnspecified</a></td></tr>
@@ -344,7 +365,7 @@
 </div>
 </div>
 <a id="a86b94cfa47729bef2e04dce1a9086074"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a86b94cfa47729bef2e04dce1a9086074">&#9670;&nbsp;</a></span>openStream()</h2>
+<h2 class="memtitle"><span class="permalink"><a href="#a86b94cfa47729bef2e04dce1a9086074">&#9670;&nbsp;</a></span>openStream() <span class="overload">[1/2]</span></h2>
 
 <div class="memitem">
 <div class="memproto">
@@ -360,6 +381,7 @@
 </div><div class="memdoc">
 <p>Create and open a stream object based on the current settings.</p>
 <p>The caller owns the pointer to the <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> object.</p>
+<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000004">Deprecated:</a></b></dt><dd>Use <a class="el" href="classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb">openStream(std::shared_ptr&lt;oboe::AudioStream&gt; &amp;stream)</a> instead. </dd></dl>
 <dl class="params"><dt>Parameters</dt><dd>
   <table class="params">
     <tr><td class="paramname">stream</td><td>pointer to a variable to receive the stream address </td></tr>
@@ -370,6 +392,33 @@
 
 </div>
 </div>
+<a id="a44b68216c48f8fb08a9e63178e0b0eeb"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a44b68216c48f8fb08a9e63178e0b0eeb">&#9670;&nbsp;</a></span>openStream() <span class="overload">[2/2]</span></h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> oboe::AudioStreamBuilder::openStream </td>
+          <td>(</td>
+          <td class="paramtype">std::shared_ptr&lt; <a class="el" href="classoboe_1_1_audio_stream.html">oboe::AudioStream</a> &gt; &amp;&#160;</td>
+          <td class="paramname"><em>stream</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+<p>Create and open a stream object based on the current settings.</p>
+<p>The caller shares the pointer to the <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> object. The shared_ptr is used internally by Oboe to prevent the stream from being deleted while it is being used by callbacks.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">stream</td><td>reference to a shared_ptr to receive the stream address </td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>OBOE_OK if successful or a negative error code </dd></dl>
+
+</div>
+</div>
 <a id="a38c6d6c5e718df1e3ac69daaac47c391"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a38c6d6c5e718df1e3ac69daaac47c391">&#9670;&nbsp;</a></span>setAudioApi()</h2>
 
@@ -466,6 +515,7 @@
 </table>
 </div><div class="memdoc">
 <p>Specifies an object to handle data or error related callbacks from the underlying API.</p>
+<p>This is the equivalent of calling both <a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">setDataCallback()</a> and <a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">setErrorCallback()</a>.</p>
 <p><b>Important: See <a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> for restrictions on what may be called from the callback methods.</b></p>
 <p>When an error callback occurs, the associated stream will be stopped and closed in a separate thread.</p>
 <p>A note on why the streamCallback parameter is a raw pointer rather than a smart pointer:</p>
@@ -560,8 +610,8 @@
   </tr>
 </table>
 </div><div class="memdoc">
-<p>Set the type of audio data that the stream will carry.</p>
-<p>The system will use this information to optimize the behavior of the stream. This could, for example, affect whether a stream is paused when a notification occurs.</p>
+<p>Set the type of audio data that an output stream will carry.</p>
+<p>The system will use this information to optimize the behavior of the stream. This could, for example, affect whether a stream is paused when a notification occurs. The contentType is ignored for input streams.</p>
 <p>The default, if you do not call this function, is ContentType::Music.</p>
 <p>Added in API level 28.</p>
 <dl class="params"><dt>Parameters</dt><dd>
@@ -573,6 +623,41 @@
 
 </div>
 </div>
+<a id="acad307720e0f370267b4e2f9a626ae70"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#acad307720e0f370267b4e2f9a626ae70">&#9670;&nbsp;</a></span>setDataCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>* oboe::AudioStreamBuilder::setDataCallback </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a> *&#160;</td>
+          <td class="paramname"><em>dataCallback</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Specifies an object to handle data related callbacks from the underlying API.</p>
+<p><b>Important: See <a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> for restrictions on what may be called from the callback methods.</b></p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">dataCallback</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the builder so calls can be chained </dd></dl>
+
+</div>
+</div>
 <a id="af36ddcd00686a9e1de661bdac0685a8e"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#af36ddcd00686a9e1de661bdac0685a8e">&#9670;&nbsp;</a></span>setDeviceId()</h2>
 
@@ -643,6 +728,42 @@
 
 </div>
 </div>
+<a id="aacb66f530bfc6f545911b5e169774567"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#aacb66f530bfc6f545911b5e169774567">&#9670;&nbsp;</a></span>setErrorCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>* oboe::AudioStreamBuilder::setErrorCallback </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a> *&#160;</td>
+          <td class="paramname"><em>errorCallback</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Specifies an object to handle error related callbacks from the underlying API. This can occur when a stream is disconnected because a headset is plugged in or unplugged. It can also occur if the audio service fails or if an exclusive stream is stolen by another stream.</p>
+<p><b>Important: See <a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> for restrictions on what may be called from the callback methods.</b></p>
+<p><b>When an error callback occurs, the associated stream must be stopped and closed in a separate thread.</b></p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">errorCallback</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the builder so calls can be chained </dd></dl>
+
+</div>
+</div>
 <a id="aa2e1d2d73cd6c2eb9f349bf2fe5f6515"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">&#9670;&nbsp;</a></span>setFormat()</h2>
 
@@ -722,6 +843,33 @@
   </tr>
 </table>
 </div><div class="memdoc">
+<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000003">Deprecated:</a></b></dt><dd>use <code>setFramesPerDataCallback</code> instead. </dd></dl>
+
+</div>
+</div>
+<a id="afb8e95e80df7edd1af27af490438785e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#afb8e95e80df7edd1af27af490438785e">&#9670;&nbsp;</a></span>setFramesPerDataCallback()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname"><a class="el" href="classoboe_1_1_audio_stream_builder.html">AudioStreamBuilder</a>* oboe::AudioStreamBuilder::setFramesPerDataCallback </td>
+          <td>(</td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>framesPerCallback</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
 <p>Request a specific number of frames for the data callback.</p>
 <p>Default is kUnspecified. If the value is unspecified then the actual number may vary from callback to callback.</p>
 <p>If an application can handle a varying number of frames then we recommend leaving this unspecified. This allow the underlying API to optimize the callbacks. But if your application is, for example, doing FFTs or other block oriented operations, then call this function to get the sizes you need.</p>
@@ -961,8 +1109,8 @@
   </tr>
 </table>
 </div><div class="memdoc">
-<p>Set the intended use case for the stream.</p>
-<p>The system will use this information to optimize the behavior of the stream. This could, for example, affect how volume and focus is handled for the stream.</p>
+<p>Set the intended use case for an output stream.</p>
+<p>The system will use this information to optimize the behavior of the stream. This could, for example, affect how volume and focus is handled for the stream. The usage is ignored for input streams.</p>
 <p>The default, if you do not call this function, is <a class="el" href="namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74">Usage::Media</a>.</p>
 <p>Added in API level 28.</p>
 <dl class="params"><dt>Parameters</dt><dd>
diff --git a/docs/reference/classoboe_1_1_audio_stream_callback-members.html b/docs/reference/classoboe_1_1_audio_stream_callback-members.html
index c4bb1b0..fac5145 100644
--- a/docs/reference/classoboe_1_1_audio_stream_callback-members.html
+++ b/docs/reference/classoboe_1_1_audio_stream_callback-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -74,10 +74,13 @@
 
 <p>This is the complete list of members for <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>, including all inherited members.</p>
 <table class="directory">
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">onAudioReady</a>(AudioStream *oboeStream, void *audioData, int32_t numFrames)=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">onErrorAfterClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">onErrorBeforeClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">onAudioReady</a>(AudioStream *audioStream, void *audioData, int32_t numFrames)=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamDataCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamErrorCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/classoboe_1_1_audio_stream_callback.html b/docs/reference/classoboe_1_1_audio_stream_callback.html
index d99467e..8dea790 100644
--- a/docs/reference/classoboe_1_1_audio_stream_callback.html
+++ b/docs/reference/classoboe_1_1_audio_stream_callback.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -68,10 +68,9 @@
 </div><!-- top -->
 <div class="header">
   <div class="summary">
-<a href="#pub-methods">Public Member Functions</a> &#124;
 <a href="classoboe_1_1_audio_stream_callback-members.html">List of all members</a>  </div>
   <div class="headertitle">
-<div class="title">oboe::AudioStreamCallback Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div>  </div>
+<div class="title">oboe::AudioStreamCallback Class Reference</div>  </div>
 </div><!--header-->
 <div class="contents">
 
@@ -82,206 +81,32 @@
  <div class="center">
   <img src="classoboe_1_1_audio_stream_callback.png" usemap="#oboe::AudioStreamCallback_map" alt=""/>
   <map id="oboe::AudioStreamCallback_map" name="oboe::AudioStreamCallback_map">
-<area href="classoboe_1_1_stabilized_callback.html" alt="oboe::StabilizedCallback" shape="rect" coords="0,56,167,80"/>
+<area href="classoboe_1_1_audio_stream_data_callback.html" alt="oboe::AudioStreamDataCallback" shape="rect" coords="0,0,197,24"/>
+<area href="classoboe_1_1_audio_stream_error_callback.html" alt="oboe::AudioStreamErrorCallback" shape="rect" coords="207,0,404,24"/>
+<area href="classoboe_1_1_stabilized_callback.html" alt="oboe::StabilizedCallback" shape="rect" coords="103,112,300,136"/>
   </map>
 </div></div>
 <table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
-Public Member Functions</h2></td></tr>
-<tr class="memitem:af3a7c44f0254abe6e5e5bb566e2317df"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">onAudioReady</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, void *audioData, int32_t numFrames)=0</td></tr>
-<tr class="separator:af3a7c44f0254abe6e5e5bb566e2317df"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a77ceb641f941164d7b4d4c51c9a888b9"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">onErrorBeforeClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
-<tr class="separator:a77ceb641f941164d7b4d4c51c9a888b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a57a1b21efc764e8bbf8d92008a993bfd"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">onErrorAfterClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
-<tr class="separator:a57a1b21efc764e8bbf8d92008a993bfd"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="inherited"></a>
+Additional Inherited Members</h2></td></tr>
+<tr class="inherit_header pub_methods_classoboe_1_1_audio_stream_data_callback"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classoboe_1_1_audio_stream_data_callback')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td></tr>
+<tr class="memitem:ad8a3a9f609df5fd3a5d885cbe1b2204d inherit pub_methods_classoboe_1_1_audio_stream_data_callback"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">onAudioReady</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *audioStream, void *audioData, int32_t numFrames)=0</td></tr>
+<tr class="separator:ad8a3a9f609df5fd3a5d885cbe1b2204d inherit pub_methods_classoboe_1_1_audio_stream_data_callback"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header pub_methods_classoboe_1_1_audio_stream_error_callback"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classoboe_1_1_audio_stream_error_callback')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td></tr>
+<tr class="memitem:a5ad4b8936746ecbb2160a9389b117fc3 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memItemLeft" align="right" valign="top">virtual bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a5ad4b8936746ecbb2160a9389b117fc3 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a4eb1e4916b71d8231e97b19898bc9bf0 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a4eb1e4916b71d8231e97b19898bc9bf0 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a76bd3ef3e00396e10c21812003654cfe inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a76bd3ef3e00396e10c21812003654cfe inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a> defines a callback interface for:</p>
-<p>1) moving data to/from an audio stream using <code>onAudioReady</code> 2) being alerted when a stream has an error using <code>onError*</code> methods </p>
-</div><h2 class="groupheader">Member Function Documentation</h2>
-<a id="af3a7c44f0254abe6e5e5bb566e2317df"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#af3a7c44f0254abe6e5e5bb566e2317df">&#9670;&nbsp;</a></span>onAudioReady()</h2>
-
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">virtual <a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> oboe::AudioStreamCallback::onAudioReady </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
-          <td class="paramname"><em>oboeStream</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">void *&#160;</td>
-          <td class="paramname"><em>audioData</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int32_t&#160;</td>
-          <td class="paramname"><em>numFrames</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-<p>A buffer is ready for processing.</p>
-<p>For an output stream, this function should render and write numFrames of data in the stream's current data format to the audioData buffer.</p>
-<p>For an input stream, this function should read and process numFrames of data from the audioData buffer.</p>
-<p>The audio data is passed through the buffer. So do NOT call read() or write() on the stream that is making the callback.</p>
-<p>Note that numFrames can vary unless <a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">AudioStreamBuilder::setFramesPerCallback()</a> is called.</p>
-<p>Also note that this callback function should be considered a "real-time" function. It must not do anything that could cause an unbounded delay because that can cause the audio to glitch or pop.</p>
-<p>These are things the function should NOT do: </p><ul>
-<li>
-allocate memory using, for example, malloc() or new </li>
-<li>
-any file operations such as opening, closing, reading or writing </li>
-<li>
-any network operations such as streaming </li>
-<li>
-use any mutexes or other synchronization primitives </li>
-<li>
-sleep </li>
-<li>
-oboeStream-&gt;stop(), pause(), flush() or close() </li>
-<li>
-oboeStream-&gt;read() </li>
-<li>
-oboeStream-&gt;write() </li>
-</ul>
-<p>The following are OK to call from the data callback: </p><ul>
-<li>
-oboeStream-&gt;get*() </li>
-<li>
-<a class="el" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">oboe::convertToText()</a> </li>
-<li>
-oboeStream-&gt;setBufferSizeInFrames() </li>
-</ul>
-<p>If you need to move data, eg. MIDI commands, in or out of the callback function then we recommend the use of non-blocking techniques such as an atomic FIFO.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
-    <tr><td class="paramname">audioData</td><td>buffer containing input data or a place to put output data </td></tr>
-    <tr><td class="paramname">numFrames</td><td>number of frames to be processed </td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>DataCallbackResult::Continue or DataCallbackResult::Stop </dd></dl>
-
-<p>Implemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback</a>.</p>
-
-</div>
-</div>
-<a id="a57a1b21efc764e8bbf8d92008a993bfd"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a57a1b21efc764e8bbf8d92008a993bfd">&#9670;&nbsp;</a></span>onErrorAfterClose()</h2>
-
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">virtual void oboe::AudioStreamCallback::onErrorAfterClose </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
-          <td class="paramname">, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td>
-          <td class="paramname">&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-<p>This will be called when an error occurs on a stream or when the stream is disconnected. The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe. So the underlying stream cannot be referenced. But you can still query most parameters.</p>
-<p>This callback could be used to reopen a new stream on another device. You can safely delete the old <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> in this method.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
-    <tr><td class="paramname">error</td><td></td></tr>
-  </table>
-  </dd>
-</dl>
-
-<p>Reimplemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">oboe::StabilizedCallback</a>.</p>
-
-</div>
-</div>
-<a id="a77ceb641f941164d7b4d4c51c9a888b9"></a>
-<h2 class="memtitle"><span class="permalink"><a href="#a77ceb641f941164d7b4d4c51c9a888b9">&#9670;&nbsp;</a></span>onErrorBeforeClose()</h2>
-
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">virtual void oboe::AudioStreamCallback::onErrorBeforeClose </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
-          <td class="paramname">, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td>
-          <td class="paramname">&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-<p>This will be called when an error occurs on a stream or when the stream is disconnected.</p>
-<p>Note that this will be called on a different thread than the <a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">onAudioReady()</a> thread. This thread will be created by Oboe.</p>
-<p>The underlying stream will already be stopped by Oboe but not yet closed. So the stream can be queried.</p>
-<p>Do not close or delete the stream in this method because it will be closed after this method returns.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
-    <tr><td class="paramname">error</td><td></td></tr>
-  </table>
-  </dd>
-</dl>
-
-<p>Reimplemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">oboe::StabilizedCallback</a>.</p>
-
-</div>
-</div>
-<hr/>The documentation for this class was generated from the following file:<ul>
+<p>1) moving data to/from an audio stream using <code>onAudioReady</code> 2) being alerted when a stream has an error using <code>onError*</code> methods</p>
+<p>It is used with <a class="el" href="classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd">AudioStreamBuilder::setCallback()</a>.</p>
+<p>It combines the interfaces defined by <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> and <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a>. This was the original callback object. We now recommend using the individual interfaces and using setDataCallback() and setErrorCallback().</p>
+<dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000005">Deprecated:</a></b></dt><dd>Use <code><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a></code> and <code><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a></code> instead </dd></dl>
+</div><hr/>The documentation for this class was generated from the following file:<ul>
 <li>include/oboe/<a class="el" href="_audio_stream_callback_8h_source.html">AudioStreamCallback.h</a></li>
 </ul>
 </div><!-- contents -->
diff --git a/docs/reference/classoboe_1_1_audio_stream_callback.png b/docs/reference/classoboe_1_1_audio_stream_callback.png
index d3580d5..8db5436 100644
--- a/docs/reference/classoboe_1_1_audio_stream_callback.png
+++ b/docs/reference/classoboe_1_1_audio_stream_callback.png
Binary files differ
diff --git a/docs/reference/classoboe_1_1_audio_stream_data_callback-members.html b/docs/reference/classoboe_1_1_audio_stream_data_callback-members.html
new file mode 100644
index 0000000..89075e4
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_data_callback-members.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="headertitle">
+<div class="title">oboe::AudioStreamDataCallback Member List</div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">onAudioReady</a>(AudioStream *audioStream, void *audioData, int32_t numFrames)=0</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamDataCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+</table></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_audio_stream_data_callback.html b/docs/reference/classoboe_1_1_audio_stream_data_callback.html
new file mode 100644
index 0000000..45c65ac
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_data_callback.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: oboe::AudioStreamDataCallback Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="classoboe_1_1_audio_stream_data_callback-members.html">List of all members</a>  </div>
+  <div class="headertitle">
+<div class="title">oboe::AudioStreamDataCallback Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p><code>#include &lt;<a class="el" href="_audio_stream_callback_8h_source.html">AudioStreamCallback.h</a>&gt;</code></p>
+<div class="dynheader">
+Inheritance diagram for oboe::AudioStreamDataCallback:</div>
+<div class="dyncontent">
+ <div class="center">
+  <img src="classoboe_1_1_audio_stream_data_callback.png" usemap="#oboe::AudioStreamDataCallback_map" alt=""/>
+  <map id="oboe::AudioStreamDataCallback_map" name="oboe::AudioStreamDataCallback_map">
+<area href="classoboe_1_1_audio_stream_callback.html" alt="oboe::AudioStreamCallback" shape="rect" coords="0,56,193,80"/>
+<area href="classoboe_1_1_stabilized_callback.html" alt="oboe::StabilizedCallback" shape="rect" coords="0,112,193,136"/>
+  </map>
+</div></div>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:ad8a3a9f609df5fd3a5d885cbe1b2204d"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">onAudioReady</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *audioStream, void *audioData, int32_t numFrames)=0</td></tr>
+<tr class="separator:ad8a3a9f609df5fd3a5d885cbe1b2204d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a> defines a callback interface for moving data to/from an audio stream using <code>onAudioReady</code> 2) being alerted when a stream has an error using <code>onError*</code> methods</p>
+<p>It is used with <a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">AudioStreamBuilder::setDataCallback()</a>. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="ad8a3a9f609df5fd3a5d885cbe1b2204d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad8a3a9f609df5fd3a5d885cbe1b2204d">&#9670;&nbsp;</a></span>onAudioReady()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual <a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> oboe::AudioStreamDataCallback::onAudioReady </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
+          <td class="paramname"><em>audioStream</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">void *&#160;</td>
+          <td class="paramname"><em>audioData</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int32_t&#160;</td>
+          <td class="paramname"><em>numFrames</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>A buffer is ready for processing.</p>
+<p>For an output stream, this function should render and write numFrames of data in the stream's current data format to the audioData buffer.</p>
+<p>For an input stream, this function should read and process numFrames of data from the audioData buffer.</p>
+<p>The audio data is passed through the buffer. So do NOT call read() or write() on the stream that is making the callback.</p>
+<p>Note that numFrames can vary unless <a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">AudioStreamBuilder::setFramesPerCallback()</a> is called.</p>
+<p>Also note that this callback function should be considered a "real-time" function. It must not do anything that could cause an unbounded delay because that can cause the audio to glitch or pop.</p>
+<p>These are things the function should NOT do: </p><ul>
+<li>
+allocate memory using, for example, malloc() or new </li>
+<li>
+any file operations such as opening, closing, reading or writing </li>
+<li>
+any network operations such as streaming </li>
+<li>
+use any mutexes or other synchronization primitives </li>
+<li>
+sleep </li>
+<li>
+oboeStream-&gt;stop(), pause(), flush() or close() </li>
+<li>
+oboeStream-&gt;read() </li>
+<li>
+oboeStream-&gt;write() </li>
+</ul>
+<p>The following are OK to call from the data callback: </p><ul>
+<li>
+oboeStream-&gt;get*() </li>
+<li>
+<a class="el" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">oboe::convertToText()</a> </li>
+<li>
+oboeStream-&gt;setBufferSizeInFrames() </li>
+</ul>
+<p>If you need to move data, eg. MIDI commands, in or out of the callback function then we recommend the use of non-blocking techniques such as an atomic FIFO.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">audioData</td><td>buffer containing input data or a place to put output data </td></tr>
+    <tr><td class="paramname">numFrames</td><td>number of frames to be processed </td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>DataCallbackResult::Continue or DataCallbackResult::Stop </dd></dl>
+
+<p>Implemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>include/oboe/<a class="el" href="_audio_stream_callback_8h_source.html">AudioStreamCallback.h</a></li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_audio_stream_data_callback.png b/docs/reference/classoboe_1_1_audio_stream_data_callback.png
new file mode 100644
index 0000000..ac644c4
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_data_callback.png
Binary files differ
diff --git a/docs/reference/classoboe_1_1_audio_stream_error_callback-members.html b/docs/reference/classoboe_1_1_audio_stream_error_callback-members.html
new file mode 100644
index 0000000..0b6309f
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_error_callback-members.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="headertitle">
+<div class="title">oboe::AudioStreamErrorCallback Member List</div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamErrorCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+</table></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_audio_stream_error_callback.html b/docs/reference/classoboe_1_1_audio_stream_error_callback.html
new file mode 100644
index 0000000..1569e21
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_error_callback.html
@@ -0,0 +1,260 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: oboe::AudioStreamErrorCallback Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="classoboe_1_1_audio_stream_error_callback-members.html">List of all members</a>  </div>
+  <div class="headertitle">
+<div class="title">oboe::AudioStreamErrorCallback Class Reference</div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p><code>#include &lt;<a class="el" href="_audio_stream_callback_8h_source.html">AudioStreamCallback.h</a>&gt;</code></p>
+<div class="dynheader">
+Inheritance diagram for oboe::AudioStreamErrorCallback:</div>
+<div class="dyncontent">
+ <div class="center">
+  <img src="classoboe_1_1_audio_stream_error_callback.png" usemap="#oboe::AudioStreamErrorCallback_map" alt=""/>
+  <map id="oboe::AudioStreamErrorCallback_map" name="oboe::AudioStreamErrorCallback_map">
+<area href="classoboe_1_1_audio_stream_callback.html" alt="oboe::AudioStreamCallback" shape="rect" coords="0,56,197,80"/>
+<area href="classoboe_1_1_stabilized_callback.html" alt="oboe::StabilizedCallback" shape="rect" coords="0,112,197,136"/>
+  </map>
+</div></div>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a5ad4b8936746ecbb2160a9389b117fc3"><td class="memItemLeft" align="right" valign="top">virtual bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a5ad4b8936746ecbb2160a9389b117fc3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a4eb1e4916b71d8231e97b19898bc9bf0"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a4eb1e4916b71d8231e97b19898bc9bf0"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a76bd3ef3e00396e10c21812003654cfe"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a76bd3ef3e00396e10c21812003654cfe"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a> defines a callback interface for being alerted when a stream has an error or is disconnected using <code>onError*</code> methods.</p>
+<p>It is used with <a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">AudioStreamBuilder::setErrorCallback()</a>. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a5ad4b8936746ecbb2160a9389b117fc3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a5ad4b8936746ecbb2160a9389b117fc3">&#9670;&nbsp;</a></span>onError()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual bool oboe::AudioStreamErrorCallback::onError </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
+          <td class="paramname">, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td>
+          <td class="paramname">&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>This will be called before other <code>onError</code> methods when an error occurs on a stream, such as when the stream is disconnected.</p>
+<p>It can be used to override and customize the normal error processing. Use of this method is considered an advanced technique. It might, for example, be used if an app want to use a high level lock when closing and reopening a stream. Or it might be used when an app want to signal a management thread that handles all of the stream state.</p>
+<p>If this method returns false it indicates that the stream has *not been stopped and closed by the application. In this case it will be stopped by Oboe in the following way: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">onErrorBeforeClose()</a> will be called, then the stream will be closed and <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">onErrorAfterClose()</a> will be closed.</p>
+<p>If this method returns true it indicates that the stream <em>has</em> been stopped and closed by the application and Oboe will not do this. In that case, the app MUST stop() and close() the stream.</p>
+<p>This method will be called on a thread created by Oboe.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">error</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>true if the stream has been stopped and closed, false if not </dd></dl>
+
+</div>
+</div>
+<a id="a76bd3ef3e00396e10c21812003654cfe"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a76bd3ef3e00396e10c21812003654cfe">&#9670;&nbsp;</a></span>onErrorAfterClose()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual void oboe::AudioStreamErrorCallback::onErrorAfterClose </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
+          <td class="paramname">, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td>
+          <td class="paramname">&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>This will be called when an error occurs on a stream, such as when the stream is disconnected, and if <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError()</a> returns false (indicating that the error has not already been handled).</p>
+<p>The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe. So the underlying stream cannot be referenced. But you can still query most parameters.</p>
+<p>This callback could be used to reopen a new stream on another device.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">error</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+
+<p>Reimplemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">oboe::StabilizedCallback</a>.</p>
+
+</div>
+</div>
+<a id="a4eb1e4916b71d8231e97b19898bc9bf0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a4eb1e4916b71d8231e97b19898bc9bf0">&#9670;&nbsp;</a></span>onErrorBeforeClose()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual void oboe::AudioStreamErrorCallback::onErrorBeforeClose </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
+          <td class="paramname">, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>&#160;</td>
+          <td class="paramname">&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>This will be called when an error occurs on a stream, such as when the stream is disconnected, and if <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError()</a> returns false (indicating that the error has not already been handled).</p>
+<p>Note that this will be called on a thread created by Oboe.</p>
+<p>The underlying stream will already be stopped by Oboe but not yet closed. So the stream can be queried.</p>
+<p>Do not close or delete the stream in this method because it will be closed after this method returns.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">error</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+
+<p>Reimplemented in <a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">oboe::StabilizedCallback</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>include/oboe/<a class="el" href="_audio_stream_callback_8h_source.html">AudioStreamCallback.h</a></li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_audio_stream_error_callback.png b/docs/reference/classoboe_1_1_audio_stream_error_callback.png
new file mode 100644
index 0000000..54c5ef2
--- /dev/null
+++ b/docs/reference/classoboe_1_1_audio_stream_error_callback.png
Binary files differ
diff --git a/docs/reference/classoboe_1_1_default_stream_values-members.html b/docs/reference/classoboe_1_1_default_stream_values-members.html
index 48ecabe..fe2013f 100644
--- a/docs/reference/classoboe_1_1_default_stream_values-members.html
+++ b/docs/reference/classoboe_1_1_default_stream_values-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/classoboe_1_1_default_stream_values.html b/docs/reference/classoboe_1_1_default_stream_values.html
index b23f727..282f323 100644
--- a/docs/reference/classoboe_1_1_default_stream_values.html
+++ b/docs/reference/classoboe_1_1_default_stream_values.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/classoboe_1_1_latency_tuner-members.html b/docs/reference/classoboe_1_1_latency_tuner-members.html
index 21ebcd3..55dcbe9 100644
--- a/docs/reference/classoboe_1_1_latency_tuner-members.html
+++ b/docs/reference/classoboe_1_1_latency_tuner-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -74,10 +74,14 @@
 
 <p>This is the complete list of members for <a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a>, including all inherited members.</p>
 <table class="directory">
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>getBufferSizeIncrement</b>() const (defined in <a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>getMinimumBufferSize</b>() const (defined in <a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4">isAtMaximumBufferSize</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#a0263b9a55825c0a403653b2b508073ea">LatencyTuner</a>(AudioStream &amp;stream)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">explicit</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#ab437bd10605af9e5733d043f8adc0b43">LatencyTuner</a>(AudioStream &amp;stream, int32_t maximumBufferSize)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">explicit</span></td></tr>
   <tr><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">requestReset</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">setBufferSizeIncrement</a>(int32_t sizeIncrement)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">setMinimumBufferSize</a>(int32_t bufferSize)</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html#ad2be756965e6a9af3114008eda892174">tune</a>()</td><td class="entry"><a class="el" href="classoboe_1_1_latency_tuner.html">oboe::LatencyTuner</a></td><td class="entry"></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
diff --git a/docs/reference/classoboe_1_1_latency_tuner.html b/docs/reference/classoboe_1_1_latency_tuner.html
index 849d0db..4167acc 100644
--- a/docs/reference/classoboe_1_1_latency_tuner.html
+++ b/docs/reference/classoboe_1_1_latency_tuner.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -89,6 +89,16 @@
 <tr class="separator:a6c0142e08dc65eda8f758b4794450867"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a45c013fd6787ad09d328385d6314c4d4"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4">isAtMaximumBufferSize</a> ()</td></tr>
 <tr class="separator:a45c013fd6787ad09d328385d6314c4d4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:adc96aa53b18a051b6ccdacb838139bf8"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">setMinimumBufferSize</a> (int32_t bufferSize)</td></tr>
+<tr class="separator:adc96aa53b18a051b6ccdacb838139bf8"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:aaba4b3f075ed8d7c7ad4cad392545c08"><td class="memItemLeft" align="right" valign="top"><a id="aaba4b3f075ed8d7c7ad4cad392545c08"></a>
+int32_t&#160;</td><td class="memItemRight" valign="bottom"><b>getMinimumBufferSize</b> () const</td></tr>
+<tr class="separator:aaba4b3f075ed8d7c7ad4cad392545c08"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a2684b30205126c8acd2f75d01cce05db"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">setBufferSizeIncrement</a> (int32_t sizeIncrement)</td></tr>
+<tr class="separator:a2684b30205126c8acd2f75d01cce05db"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a5ea6114ac4f78f3e050d405168905123"><td class="memItemLeft" align="right" valign="top"><a id="a5ea6114ac4f78f3e050d405168905123"></a>
+int32_t&#160;</td><td class="memItemRight" valign="bottom"><b>getBufferSizeIncrement</b> () const</td></tr>
+<tr class="separator:a5ea6114ac4f78f3e050d405168905123"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p><a class="el" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a> can be used to dynamically tune the latency of an output stream. It adjusts the stream's bufferSize by monitoring the number of underruns.</p>
@@ -211,6 +221,72 @@
 
 </div>
 </div>
+<a id="a2684b30205126c8acd2f75d01cce05db"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a2684b30205126c8acd2f75d01cce05db">&#9670;&nbsp;</a></span>setBufferSizeIncrement()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">void oboe::LatencyTuner::setBufferSizeIncrement </td>
+          <td>(</td>
+          <td class="paramtype">int32_t&#160;</td>
+          <td class="paramname"><em>sizeIncrement</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Set the amount the bufferSize will be incremented while tuning. By default, this will be one burst.</p>
+<p>Note that AAudio will quantize the buffer size to a multiple of the burstSize. So the final buffer sizes may not be a multiple of this increment.</p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">sizeIncrement</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<a id="adc96aa53b18a051b6ccdacb838139bf8"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#adc96aa53b18a051b6ccdacb838139bf8">&#9670;&nbsp;</a></span>setMinimumBufferSize()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">void oboe::LatencyTuner::setMinimumBufferSize </td>
+          <td>(</td>
+          <td class="paramtype">int32_t&#160;</td>
+          <td class="paramname"><em>bufferSize</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Set the minimum bufferSize in frames that is used when the tuner is reset. You may wish to call <a class="el" href="classoboe_1_1_latency_tuner.html#a6c0142e08dc65eda8f758b4794450867">requestReset()</a> after calling this. </p><dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">bufferSize</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
 <a id="ad2be756965e6a9af3114008eda892174"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#ad2be756965e6a9af3114008eda892174">&#9670;&nbsp;</a></span>tune()</h2>
 
diff --git a/docs/reference/classoboe_1_1_oboe_globals-members.html b/docs/reference/classoboe_1_1_oboe_globals-members.html
new file mode 100644
index 0000000..9ddac6f
--- /dev/null
+++ b/docs/reference/classoboe_1_1_oboe_globals-members.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_oboe_globals.html">OboeGlobals</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="headertitle">
+<div class="title">oboe::OboeGlobals Member List</div>  </div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="classoboe_1_1_oboe_globals.html">oboe::OboeGlobals</a>, including all inherited members.</p>
+<table class="directory">
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>areWorkaroundsEnabled</b>() (defined in <a class="el" href="classoboe_1_1_oboe_globals.html">oboe::OboeGlobals</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_oboe_globals.html">oboe::OboeGlobals</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">static</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">setWorkaroundsEnabled</a>(bool enabled)</td><td class="entry"><a class="el" href="classoboe_1_1_oboe_globals.html">oboe::OboeGlobals</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">static</span></td></tr>
+</table></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_oboe_globals.html b/docs/reference/classoboe_1_1_oboe_globals.html
new file mode 100644
index 0000000..c582e30
--- /dev/null
+++ b/docs/reference/classoboe_1_1_oboe_globals.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Oboe: oboe::OboeGlobals Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td id="projectalign" style="padding-left: 0.5em;">
+   <div id="projectname">Oboe
+   &#160;<span id="projectnumber">1.5</span>
+   </div>
+   <div id="projectbrief">A library for creating real-time audio apps on Android</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.15 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */</script>
+<div id="main-nav"></div>
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div id="nav-path" class="navpath">
+  <ul>
+<li class="navelem"><a class="el" href="namespaceoboe.html">oboe</a></li><li class="navelem"><a class="el" href="classoboe_1_1_oboe_globals.html">OboeGlobals</a></li>  </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+  <div class="summary">
+<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
+<a href="classoboe_1_1_oboe_globals-members.html">List of all members</a>  </div>
+  <div class="headertitle">
+<div class="title">oboe::OboeGlobals Class Reference</div>  </div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-static-methods"></a>
+Static Public Member Functions</h2></td></tr>
+<tr class="memitem:a37ba77c944e44c36a6b599eb4d630c9f"><td class="memItemLeft" align="right" valign="top"><a id="a37ba77c944e44c36a6b599eb4d630c9f"></a>
+static bool&#160;</td><td class="memItemRight" valign="bottom"><b>areWorkaroundsEnabled</b> ()</td></tr>
+<tr class="separator:a37ba77c944e44c36a6b599eb4d630c9f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:af2b8af764c5a5e6fc007b7725117303b"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">setWorkaroundsEnabled</a> (bool enabled)</td></tr>
+<tr class="separator:af2b8af764c5a5e6fc007b7725117303b"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="af2b8af764c5a5e6fc007b7725117303b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#af2b8af764c5a5e6fc007b7725117303b">&#9670;&nbsp;</a></span>setWorkaroundsEnabled()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">static void oboe::OboeGlobals::setWorkaroundsEnabled </td>
+          <td>(</td>
+          <td class="paramtype">bool&#160;</td>
+          <td class="paramname"><em>enabled</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">static</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+<p>Disable this when writing tests to reproduce bugs in AAudio or OpenSL ES that have workarounds in Oboe. </p><dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">enabled</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>include/oboe/<a class="el" href="_definitions_8h_source.html">Definitions.h</a></li>
+</ul>
+</div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.15
+</small></address>
+</body>
+</html>
diff --git a/docs/reference/classoboe_1_1_result_with_value-members.html b/docs/reference/classoboe_1_1_result_with_value-members.html
index 4880127..a8fe74d 100644
--- a/docs/reference/classoboe_1_1_result_with_value-members.html
+++ b/docs/reference/classoboe_1_1_result_with_value-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/classoboe_1_1_result_with_value.html b/docs/reference/classoboe_1_1_result_with_value.html
index 3afcf32..58a0826 100644
--- a/docs/reference/classoboe_1_1_result_with_value.html
+++ b/docs/reference/classoboe_1_1_result_with_value.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/classoboe_1_1_stabilized_callback-members.html b/docs/reference/classoboe_1_1_stabilized_callback-members.html
index 722ba64..5b58d7b 100644
--- a/docs/reference/classoboe_1_1_stabilized_callback-members.html
+++ b/docs/reference/classoboe_1_1_stabilized_callback-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -75,10 +75,13 @@
 <p>This is the complete list of members for <a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a>, including all inherited members.</p>
 <table class="directory">
   <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">onAudioReady</a>(AudioStream *oboeStream, void *audioData, int32_t numFrames) override</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
-  <tr><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">onErrorAfterClose</a>(AudioStream *oboeStream, Result error) override</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">onErrorBeforeClose</a>(AudioStream *oboeStream, Result error) override</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
-  <tr bgcolor="#f0f0f0"><td class="entry"><b>StabilizedCallback</b>(AudioStreamCallback *callback) (defined in <a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">explicit</span></td></tr>
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a>(AudioStream *, Result)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">onErrorAfterClose</a>(AudioStream *oboeStream, Result error) override</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">onErrorBeforeClose</a>(AudioStream *oboeStream, Result error) override</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>StabilizedCallback</b>(AudioStreamCallback *callback) (defined in <a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_stabilized_callback.html">oboe::StabilizedCallback</a></td><td class="entry"><span class="mlabel">explicit</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>~AudioStreamDataCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">oboe::AudioStreamDataCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0"><td class="entry"><b>~AudioStreamErrorCallback</b>()=default (defined in <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a>)</td><td class="entry"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
 <hr class="footer"/><address class="footer"><small>
diff --git a/docs/reference/classoboe_1_1_stabilized_callback.html b/docs/reference/classoboe_1_1_stabilized_callback.html
index d37a824..0026cd0 100644
--- a/docs/reference/classoboe_1_1_stabilized_callback.html
+++ b/docs/reference/classoboe_1_1_stabilized_callback.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -80,7 +80,9 @@
  <div class="center">
   <img src="classoboe_1_1_stabilized_callback.png" usemap="#oboe::StabilizedCallback_map" alt=""/>
   <map id="oboe::StabilizedCallback_map" name="oboe::StabilizedCallback_map">
-<area href="classoboe_1_1_audio_stream_callback.html" alt="oboe::AudioStreamCallback" shape="rect" coords="0,0,167,24"/>
+<area href="classoboe_1_1_audio_stream_callback.html" alt="oboe::AudioStreamCallback" shape="rect" coords="103,56,300,80"/>
+<area href="classoboe_1_1_audio_stream_data_callback.html" alt="oboe::AudioStreamDataCallback" shape="rect" coords="0,0,197,24"/>
+<area href="classoboe_1_1_audio_stream_error_callback.html" alt="oboe::AudioStreamErrorCallback" shape="rect" coords="207,0,404,24"/>
   </map>
 </div></div>
 <table class="memberdecls">
@@ -95,6 +97,9 @@
 <tr class="separator:a7ec0e9fca3181962ab78716bcda83e10"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:af7521da42c4b08a71e6102994f6f41f4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">onErrorAfterClose</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *oboeStream, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a> error) override</td></tr>
 <tr class="separator:af7521da42c4b08a71e6102994f6f41f4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header pub_methods_classoboe_1_1_audio_stream_error_callback"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classoboe_1_1_audio_stream_error_callback')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classoboe_1_1_audio_stream_error_callback.html">oboe::AudioStreamErrorCallback</a></td></tr>
+<tr class="memitem:a5ad4b8936746ecbb2160a9389b117fc3 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memItemLeft" align="right" valign="top">virtual bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError</a> (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *, <a class="el" href="namespaceoboe.html#a486512e787b609c80ba4436f23929af1">Result</a>)</td></tr>
+<tr class="separator:a5ad4b8936746ecbb2160a9389b117fc3 inherit pub_methods_classoboe_1_1_audio_stream_error_callback"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <h2 class="groupheader">Member Function Documentation</h2>
 <a id="ad447e12ebf732cf151655c1fbaf58a49"></a>
@@ -110,7 +115,7 @@
           <td class="memname"><a class="el" href="namespaceoboe.html#af85fc9910a287df6c5df0ed396bb75cd">DataCallbackResult</a> oboe::StabilizedCallback::onAudioReady </td>
           <td>(</td>
           <td class="paramtype"><a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> *&#160;</td>
-          <td class="paramname"><em>oboeStream</em>, </td>
+          <td class="paramname"><em>audioStream</em>, </td>
         </tr>
         <tr>
           <td class="paramkey"></td>
@@ -171,7 +176,7 @@
 <p>If you need to move data, eg. MIDI commands, in or out of the callback function then we recommend the use of non-blocking techniques such as an atomic FIFO.</p>
 <dl class="params"><dt>Parameters</dt><dd>
   <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
     <tr><td class="paramname">audioData</td><td>buffer containing input data or a place to put output data </td></tr>
     <tr><td class="paramname">numFrames</td><td>number of frames to be processed </td></tr>
   </table>
@@ -179,7 +184,7 @@
 </dl>
 <dl class="section return"><dt>Returns</dt><dd>DataCallbackResult::Continue or DataCallbackResult::Stop </dd></dl>
 
-<p>Implements <a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">oboe::AudioStreamCallback</a>.</p>
+<p>Implements <a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">oboe::AudioStreamDataCallback</a>.</p>
 
 </div>
 </div>
@@ -216,17 +221,18 @@
   </tr>
 </table>
 </div><div class="memdoc">
-<p>This will be called when an error occurs on a stream or when the stream is disconnected. The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe. So the underlying stream cannot be referenced. But you can still query most parameters.</p>
-<p>This callback could be used to reopen a new stream on another device. You can safely delete the old <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> in this method.</p>
+<p>This will be called when an error occurs on a stream, such as when the stream is disconnected, and if <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError()</a> returns false (indicating that the error has not already been handled).</p>
+<p>The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe. So the underlying stream cannot be referenced. But you can still query most parameters.</p>
+<p>This callback could be used to reopen a new stream on another device.</p>
 <dl class="params"><dt>Parameters</dt><dd>
   <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
     <tr><td class="paramname">error</td><td></td></tr>
   </table>
   </dd>
 </dl>
 
-<p>Reimplemented from <a class="el" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">oboe::AudioStreamCallback</a>.</p>
+<p>Reimplemented from <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">oboe::AudioStreamErrorCallback</a>.</p>
 
 </div>
 </div>
@@ -263,19 +269,19 @@
   </tr>
 </table>
 </div><div class="memdoc">
-<p>This will be called when an error occurs on a stream or when the stream is disconnected.</p>
-<p>Note that this will be called on a different thread than the <a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">onAudioReady()</a> thread. This thread will be created by Oboe.</p>
+<p>This will be called when an error occurs on a stream, such as when the stream is disconnected, and if <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">onError()</a> returns false (indicating that the error has not already been handled).</p>
+<p>Note that this will be called on a thread created by Oboe.</p>
 <p>The underlying stream will already be stopped by Oboe but not yet closed. So the stream can be queried.</p>
 <p>Do not close or delete the stream in this method because it will be closed after this method returns.</p>
 <dl class="params"><dt>Parameters</dt><dd>
   <table class="params">
-    <tr><td class="paramname">oboeStream</td><td>pointer to the associated stream </td></tr>
+    <tr><td class="paramname">audioStream</td><td>pointer to the associated stream </td></tr>
     <tr><td class="paramname">error</td><td></td></tr>
   </table>
   </dd>
 </dl>
 
-<p>Reimplemented from <a class="el" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">oboe::AudioStreamCallback</a>.</p>
+<p>Reimplemented from <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">oboe::AudioStreamErrorCallback</a>.</p>
 
 </div>
 </div>
diff --git a/docs/reference/classoboe_1_1_stabilized_callback.png b/docs/reference/classoboe_1_1_stabilized_callback.png
index 94b40c3..f3748f8 100644
--- a/docs/reference/classoboe_1_1_stabilized_callback.png
+++ b/docs/reference/classoboe_1_1_stabilized_callback.png
Binary files differ
diff --git a/docs/reference/deprecated.html b/docs/reference/deprecated.html
index 3d89239..6d2aa37 100644
--- a/docs/reference/deprecated.html
+++ b/docs/reference/deprecated.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -69,7 +69,15 @@
 <div class="contents">
 <div class="textblock"><dl class="reflist">
 <dt>Member <a class="el" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">oboe::AudioStream::getTimestamp</a>  (clockid_t, int64_t *, int64_t *)</dt>
-<dd><a class="anchor" id="_deprecated000001"></a>since 1.0, use <a class="el" href="classoboe_1_1_audio_stream.html#a49254e6b1b19cb6d0ca6c63058029771">AudioStream::getTimestamp(clockid_t clockId)</a> instead, which returns <a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a> </dd>
+<dd><a class="anchor" id="_deprecated000001"></a>since 1.0, use <a class="el" href="classoboe_1_1_audio_stream.html#a49254e6b1b19cb6d0ca6c63058029771">AudioStream::getTimestamp(clockid_t clockId)</a> instead, which returns <a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a>  </dd>
+<dt>Member <a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">oboe::AudioStreamBase::getFramesPerCallback</a>  () const</dt>
+<dd><a class="anchor" id="_deprecated000002"></a>use <code>getFramesPerDataCallback</code> instead.  </dd>
+<dt>Member <a class="el" href="classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074">oboe::AudioStreamBuilder::openStream</a>  (<a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> **stream)</dt>
+<dd><a class="anchor" id="_deprecated000004"></a>Use <a class="el" href="classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb">openStream(std::shared_ptr&lt;oboe::AudioStream&gt; &amp;stream)</a> instead.  </dd>
+<dt>Member <a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">oboe::AudioStreamBuilder::setFramesPerCallback</a>  (int framesPerCallback)</dt>
+<dd><a class="anchor" id="_deprecated000003"></a>use <code>setFramesPerDataCallback</code> instead.  </dd>
+<dt>Class <a class="el" href="classoboe_1_1_audio_stream_callback.html">oboe::AudioStreamCallback</a>  </dt>
+<dd><a class="anchor" id="_deprecated000005"></a>Use <code><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a></code> and <code><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a></code> instead </dd>
 </dl>
 </div></div><!-- PageDoc -->
 </div><!-- contents -->
diff --git a/docs/reference/dir_768f6301d9838e45d679001914ab2803.html b/docs/reference/dir_768f6301d9838e45d679001914ab2803.html
index ef76e48..4e1ebc5 100644
--- a/docs/reference/dir_768f6301d9838e45d679001914ab2803.html
+++ b/docs/reference/dir_768f6301d9838e45d679001914ab2803.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/dir_d44c64559bbebec7f509842c48db8b23.html b/docs/reference/dir_d44c64559bbebec7f509842c48db8b23.html
index 6bbd2b1..4620fd8 100644
--- a/docs/reference/dir_d44c64559bbebec7f509842c48db8b23.html
+++ b/docs/reference/dir_d44c64559bbebec7f509842c48db8b23.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/files.html b/docs/reference/files.html
index 6a02c5f..820f043 100644
--- a/docs/reference/files.html
+++ b/docs/reference/files.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/functions.html b/docs/reference/functions.html
index 7aa7a52..2debcc1 100644
--- a/docs/reference/functions.html
+++ b/docs/reference/functions.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -131,21 +131,24 @@
 <li>getBytesPerSample()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">oboe::AudioStream</a>
 </li>
-<li>getCallback()
-: <a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">oboe::AudioStreamBase</a>
-</li>
 <li>getChannelCount()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">oboe::AudioStreamBase</a>
 </li>
 <li>getContentType()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">oboe::AudioStreamBase</a>
 </li>
+<li>getDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">oboe::AudioStreamBase</a>
+</li>
 <li>getDeviceId()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">oboe::AudioStreamBase</a>
 </li>
 <li>getDirection()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">oboe::AudioStreamBase</a>
 </li>
+<li>getErrorCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">oboe::AudioStreamBase</a>
+</li>
 <li>getFormat()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">oboe::AudioStreamBase</a>
 </li>
@@ -155,6 +158,9 @@
 <li>getFramesPerCallback()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">oboe::AudioStreamBase</a>
 </li>
+<li>getFramesPerDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">oboe::AudioStreamBase</a>
+</li>
 <li>getFramesRead()
 : <a class="el" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">oboe::AudioStream</a>
 </li>
@@ -164,6 +170,9 @@
 <li>getInputPreset()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">oboe::AudioStreamBase</a>
 </li>
+<li>getLastErrorCallbackResult()
+: <a class="el" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">oboe::AudioStream</a>
+</li>
 <li>getPerformanceMode()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">oboe::AudioStreamBase</a>
 </li>
@@ -183,7 +192,7 @@
 : <a class="el" href="classoboe_1_1_audio_stream.html#a9d37cc6513823c685ae892626ff83ea8">oboe::AudioStream</a>
 </li>
 <li>getTimestamp()
-: <a class="el" href="classoboe_1_1_audio_stream.html#a49254e6b1b19cb6d0ca6c63058029771">oboe::AudioStream</a>
+: <a class="el" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">oboe::AudioStream</a>
 </li>
 <li>getUnderlyingStream()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">oboe::AudioStream</a>
@@ -213,9 +222,18 @@
 <li>isDataCallbackEnabled()
 : <a class="el" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">oboe::AudioStream</a>
 </li>
+<li>isDataCallbackSpecified()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">oboe::AudioStreamBase</a>
+</li>
+<li>isErrorCallbackSpecified()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">oboe::AudioStreamBase</a>
+</li>
 <li>isFormatConversionAllowed()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">oboe::AudioStreamBase</a>
 </li>
+<li>isValidConfig()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">oboe::AudioStreamBase</a>
+</li>
 <li>isXRunCountSupported()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">oboe::AudioStream</a>
 </li>
@@ -248,12 +266,18 @@
 <li>mContentType
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase</a>
 </li>
+<li>mDataCallback
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">oboe::AudioStreamBase</a>
+</li>
 <li>mDeviceId
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase</a>
 </li>
 <li>mDirection
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase</a>
 </li>
+<li>mErrorCallback
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">oboe::AudioStreamBase</a>
+</li>
 <li>mFormat
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase</a>
 </li>
@@ -287,9 +311,6 @@
 <li>mSharingMode
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase</a>
 </li>
-<li>mStreamCallback
-: <a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">oboe::AudioStreamBase</a>
-</li>
 <li>mUsage
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase</a>
 </li>
@@ -305,18 +326,21 @@
 
 <h3><a id="index_o"></a>- o -</h3><ul>
 <li>onAudioReady()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">oboe::AudioStreamDataCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback</a>
 </li>
 <li>onDefaultCallback()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">oboe::AudioStream</a>
 </li>
+<li>onError()
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">oboe::AudioStreamErrorCallback</a>
+</li>
 <li>onErrorAfterClose()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">oboe::AudioStreamErrorCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">oboe::StabilizedCallback</a>
 </li>
 <li>onErrorBeforeClose()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">oboe::AudioStreamErrorCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">oboe::StabilizedCallback</a>
 </li>
 <li>open()
@@ -388,6 +412,9 @@
 <li>setBufferCapacityInFrames()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">oboe::AudioStreamBuilder</a>
 </li>
+<li>setBufferSizeIncrement()
+: <a class="el" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">oboe::LatencyTuner</a>
+</li>
 <li>setBufferSizeInFrames()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">oboe::AudioStream</a>
 </li>
@@ -403,6 +430,9 @@
 <li>setContentType()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">oboe::AudioStreamBuilder</a>
 </li>
+<li>setDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">oboe::AudioStreamBuilder</a>
+</li>
 <li>setDataCallbackEnabled()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">oboe::AudioStream</a>
 </li>
@@ -412,6 +442,9 @@
 <li>setDirection()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">oboe::AudioStreamBuilder</a>
 </li>
+<li>setErrorCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">oboe::AudioStreamBuilder</a>
+</li>
 <li>setFormat()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">oboe::AudioStreamBuilder</a>
 </li>
@@ -421,9 +454,15 @@
 <li>setFramesPerCallback()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">oboe::AudioStreamBuilder</a>
 </li>
+<li>setFramesPerDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">oboe::AudioStreamBuilder</a>
+</li>
 <li>setInputPreset()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">oboe::AudioStreamBuilder</a>
 </li>
+<li>setMinimumBufferSize()
+: <a class="el" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">oboe::LatencyTuner</a>
+</li>
 <li>setPerformanceMode()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">oboe::AudioStreamBuilder</a>
 </li>
@@ -442,6 +481,9 @@
 <li>setUsage()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">oboe::AudioStreamBuilder</a>
 </li>
+<li>setWorkaroundsEnabled()
+: <a class="el" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">oboe::OboeGlobals</a>
+</li>
 <li>start()
 : <a class="el" href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">oboe::AudioStream</a>
 </li>
diff --git a/docs/reference/functions_func.html b/docs/reference/functions_func.html
index 7b151b1..06fd3c1 100644
--- a/docs/reference/functions_func.html
+++ b/docs/reference/functions_func.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -125,21 +125,24 @@
 <li>getBytesPerSample()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62">oboe::AudioStream</a>
 </li>
-<li>getCallback()
-: <a class="el" href="classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797">oboe::AudioStreamBase</a>
-</li>
 <li>getChannelCount()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575">oboe::AudioStreamBase</a>
 </li>
 <li>getContentType()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82">oboe::AudioStreamBase</a>
 </li>
+<li>getDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c">oboe::AudioStreamBase</a>
+</li>
 <li>getDeviceId()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21">oboe::AudioStreamBase</a>
 </li>
 <li>getDirection()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1">oboe::AudioStreamBase</a>
 </li>
+<li>getErrorCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0">oboe::AudioStreamBase</a>
+</li>
 <li>getFormat()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86">oboe::AudioStreamBase</a>
 </li>
@@ -149,6 +152,9 @@
 <li>getFramesPerCallback()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086">oboe::AudioStreamBase</a>
 </li>
+<li>getFramesPerDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38">oboe::AudioStreamBase</a>
+</li>
 <li>getFramesRead()
 : <a class="el" href="classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df">oboe::AudioStream</a>
 </li>
@@ -158,6 +164,9 @@
 <li>getInputPreset()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a">oboe::AudioStreamBase</a>
 </li>
+<li>getLastErrorCallbackResult()
+: <a class="el" href="classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75">oboe::AudioStream</a>
+</li>
 <li>getPerformanceMode()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc">oboe::AudioStreamBase</a>
 </li>
@@ -177,7 +186,7 @@
 : <a class="el" href="classoboe_1_1_audio_stream.html#a9d37cc6513823c685ae892626ff83ea8">oboe::AudioStream</a>
 </li>
 <li>getTimestamp()
-: <a class="el" href="classoboe_1_1_audio_stream.html#a49254e6b1b19cb6d0ca6c63058029771">oboe::AudioStream</a>
+: <a class="el" href="classoboe_1_1_audio_stream.html#acb8edbc17ff79993a8ed996d216fe6f3">oboe::AudioStream</a>
 </li>
 <li>getUnderlyingStream()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a5458d7130415eb4defe3dbc11d479e2f">oboe::AudioStream</a>
@@ -207,9 +216,18 @@
 <li>isDataCallbackEnabled()
 : <a class="el" href="classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831">oboe::AudioStream</a>
 </li>
+<li>isDataCallbackSpecified()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73">oboe::AudioStreamBase</a>
+</li>
+<li>isErrorCallbackSpecified()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3">oboe::AudioStreamBase</a>
+</li>
 <li>isFormatConversionAllowed()
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4">oboe::AudioStreamBase</a>
 </li>
+<li>isValidConfig()
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2">oboe::AudioStreamBase</a>
+</li>
 <li>isXRunCountSupported()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4">oboe::AudioStream</a>
 </li>
@@ -228,18 +246,21 @@
 
 <h3><a id="index_o"></a>- o -</h3><ul>
 <li>onAudioReady()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d">oboe::AudioStreamDataCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49">oboe::StabilizedCallback</a>
 </li>
 <li>onDefaultCallback()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe">oboe::AudioStream</a>
 </li>
+<li>onError()
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3">oboe::AudioStreamErrorCallback</a>
+</li>
 <li>onErrorAfterClose()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe">oboe::AudioStreamErrorCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4">oboe::StabilizedCallback</a>
 </li>
 <li>onErrorBeforeClose()
-: <a class="el" href="classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9">oboe::AudioStreamCallback</a>
+: <a class="el" href="classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0">oboe::AudioStreamErrorCallback</a>
 , <a class="el" href="classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10">oboe::StabilizedCallback</a>
 </li>
 <li>open()
@@ -305,6 +326,9 @@
 <li>setBufferCapacityInFrames()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef">oboe::AudioStreamBuilder</a>
 </li>
+<li>setBufferSizeIncrement()
+: <a class="el" href="classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db">oboe::LatencyTuner</a>
+</li>
 <li>setBufferSizeInFrames()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03">oboe::AudioStream</a>
 </li>
@@ -320,6 +344,9 @@
 <li>setContentType()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468">oboe::AudioStreamBuilder</a>
 </li>
+<li>setDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70">oboe::AudioStreamBuilder</a>
+</li>
 <li>setDataCallbackEnabled()
 : <a class="el" href="classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba">oboe::AudioStream</a>
 </li>
@@ -329,6 +356,9 @@
 <li>setDirection()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c">oboe::AudioStreamBuilder</a>
 </li>
+<li>setErrorCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567">oboe::AudioStreamBuilder</a>
+</li>
 <li>setFormat()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515">oboe::AudioStreamBuilder</a>
 </li>
@@ -338,9 +368,15 @@
 <li>setFramesPerCallback()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54">oboe::AudioStreamBuilder</a>
 </li>
+<li>setFramesPerDataCallback()
+: <a class="el" href="classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e">oboe::AudioStreamBuilder</a>
+</li>
 <li>setInputPreset()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0">oboe::AudioStreamBuilder</a>
 </li>
+<li>setMinimumBufferSize()
+: <a class="el" href="classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8">oboe::LatencyTuner</a>
+</li>
 <li>setPerformanceMode()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee">oboe::AudioStreamBuilder</a>
 </li>
@@ -359,6 +395,9 @@
 <li>setUsage()
 : <a class="el" href="classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a">oboe::AudioStreamBuilder</a>
 </li>
+<li>setWorkaroundsEnabled()
+: <a class="el" href="classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b">oboe::OboeGlobals</a>
+</li>
 <li>start()
 : <a class="el" href="classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21">oboe::AudioStream</a>
 </li>
diff --git a/docs/reference/functions_vars.html b/docs/reference/functions_vars.html
index 525a425..22e4c29 100644
--- a/docs/reference/functions_vars.html
+++ b/docs/reference/functions_vars.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -85,12 +85,18 @@
 <li>mContentType
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b">oboe::AudioStreamBase</a>
 </li>
+<li>mDataCallback
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f">oboe::AudioStreamBase</a>
+</li>
 <li>mDeviceId
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8">oboe::AudioStreamBase</a>
 </li>
 <li>mDirection
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880">oboe::AudioStreamBase</a>
 </li>
+<li>mErrorCallback
+: <a class="el" href="classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b">oboe::AudioStreamBase</a>
+</li>
 <li>mFormat
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09">oboe::AudioStreamBase</a>
 </li>
@@ -124,9 +130,6 @@
 <li>mSharingMode
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473">oboe::AudioStreamBase</a>
 </li>
-<li>mStreamCallback
-: <a class="el" href="classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4">oboe::AudioStreamBase</a>
-</li>
 <li>mUsage
 : <a class="el" href="classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c">oboe::AudioStreamBase</a>
 </li>
diff --git a/docs/reference/hierarchy.html b/docs/reference/hierarchy.html
index 74fe0ff..d7d985c 100644
--- a/docs/reference/hierarchy.html
+++ b/docs/reference/hierarchy.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -68,18 +68,22 @@
 </div><!--header-->
 <div class="contents">
 <div class="textblock">This inheritance list is sorted roughly, but not completely, alphabetically:</div><div class="directory">
-<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span>]</div><table class="directory">
+<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span>]</div><table class="directory">
 <tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_base.html" target="_self">oboe::AudioStreamBase</a></td><td class="desc"></td></tr>
 <tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream.html" target="_self">oboe::AudioStream</a></td><td class="desc"></td></tr>
 <tr id="row_0_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_builder.html" target="_self">oboe::AudioStreamBuilder</a></td><td class="desc"></td></tr>
-<tr id="row_1_"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_1_" class="arrow" onclick="toggleFolder('1_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_callback.html" target="_self">oboe::AudioStreamCallback</a></td><td class="desc"></td></tr>
-<tr id="row_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_stabilized_callback.html" target="_self">oboe::StabilizedCallback</a></td><td class="desc"></td></tr>
-<tr id="row_2_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_default_stream_values.html" target="_self">oboe::DefaultStreamValues</a></td><td class="desc"></td></tr>
-<tr id="row_3_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_frame_timestamp.html" target="_self">oboe::FrameTimestamp</a></td><td class="desc"></td></tr>
-<tr id="row_4_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_latency_tuner.html" target="_self">oboe::LatencyTuner</a></td><td class="desc"></td></tr>
-<tr id="row_5_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_result_with_value.html" target="_self">oboe::ResultWithValue&lt; T &gt;</a></td><td class="desc"></td></tr>
-<tr id="row_6_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_stream_deleter_functor.html" target="_self">oboe::StreamDeleterFunctor</a></td><td class="desc"></td></tr>
-<tr id="row_7_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_version.html" target="_self">oboe::Version</a></td><td class="desc"></td></tr>
+<tr id="row_1_"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_1_" class="arrow" onclick="toggleFolder('1_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_data_callback.html" target="_self">oboe::AudioStreamDataCallback</a></td><td class="desc"></td></tr>
+<tr id="row_1_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_1_0_" class="arrow" onclick="toggleFolder('1_0_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_callback.html" target="_self">oboe::AudioStreamCallback</a></td><td class="desc"></td></tr>
+<tr id="row_1_0_0_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_stabilized_callback.html" target="_self">oboe::StabilizedCallback</a></td><td class="desc"></td></tr>
+<tr id="row_2_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_2_" class="arrow" onclick="toggleFolder('2_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_error_callback.html" target="_self">oboe::AudioStreamErrorCallback</a></td><td class="desc"></td></tr>
+<tr id="row_2_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_audio_stream_callback.html" target="_self">oboe::AudioStreamCallback</a></td><td class="desc"></td></tr>
+<tr id="row_3_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_default_stream_values.html" target="_self">oboe::DefaultStreamValues</a></td><td class="desc"></td></tr>
+<tr id="row_4_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_frame_timestamp.html" target="_self">oboe::FrameTimestamp</a></td><td class="desc"></td></tr>
+<tr id="row_5_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_latency_tuner.html" target="_self">oboe::LatencyTuner</a></td><td class="desc"></td></tr>
+<tr id="row_6_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_oboe_globals.html" target="_self">oboe::OboeGlobals</a></td><td class="desc"></td></tr>
+<tr id="row_7_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classoboe_1_1_result_with_value.html" target="_self">oboe::ResultWithValue&lt; T &gt;</a></td><td class="desc"></td></tr>
+<tr id="row_8_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_stream_deleter_functor.html" target="_self">oboe::StreamDeleterFunctor</a></td><td class="desc"></td></tr>
+<tr id="row_9_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structoboe_1_1_version.html" target="_self">oboe::Version</a></td><td class="desc"></td></tr>
 </table>
 </div><!-- directory -->
 </div><!-- contents -->
diff --git a/docs/reference/index.html b/docs/reference/index.html
index 83fcbe3..9c83aee 100644
--- a/docs/reference/index.html
+++ b/docs/reference/index.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/namespacemembers.html b/docs/reference/namespacemembers.html
index b08bda1..9f20db9 100644
--- a/docs/reference/namespacemembers.html
+++ b/docs/reference/namespacemembers.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -117,6 +117,12 @@
 <li>Generic
 : <a class="el" href="namespaceoboe.html#a4477ed232b02e2694d9309baf55a8f06a0ba6f369e7f8a700c14afe2992290544">oboe</a>
 </li>
+<li>getPropertyInteger()
+: <a class="el" href="namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5">oboe</a>
+</li>
+<li>getPropertyString()
+: <a class="el" href="namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b">oboe</a>
+</li>
 <li>getSdkVersion()
 : <a class="el" href="namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db">oboe</a>
 </li>
diff --git a/docs/reference/namespacemembers_enum.html b/docs/reference/namespacemembers_enum.html
index cb40dab..5e2c920 100644
--- a/docs/reference/namespacemembers_enum.html
+++ b/docs/reference/namespacemembers_enum.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/namespacemembers_eval.html b/docs/reference/namespacemembers_eval.html
index 97cc30b..004d6ca 100644
--- a/docs/reference/namespacemembers_eval.html
+++ b/docs/reference/namespacemembers_eval.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/namespacemembers_func.html b/docs/reference/namespacemembers_func.html
index 52aecb3..ab074f0 100644
--- a/docs/reference/namespacemembers_func.html
+++ b/docs/reference/namespacemembers_func.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -76,6 +76,12 @@
 <li>convertToText()
 : <a class="el" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">oboe</a>
 </li>
+<li>getPropertyInteger()
+: <a class="el" href="namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5">oboe</a>
+</li>
+<li>getPropertyString()
+: <a class="el" href="namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b">oboe</a>
+</li>
 <li>getSdkVersion()
 : <a class="el" href="namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db">oboe</a>
 </li>
diff --git a/docs/reference/namespacemembers_vars.html b/docs/reference/namespacemembers_vars.html
index 70fc52c..745e0d6 100644
--- a/docs/reference/namespacemembers_vars.html
+++ b/docs/reference/namespacemembers_vars.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/namespaceoboe.html b/docs/reference/namespaceoboe.html
index c804144..a337dd7 100644
--- a/docs/reference/namespaceoboe.html
+++ b/docs/reference/namespaceoboe.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -84,12 +84,18 @@
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_callback.html">AudioStreamCallback</a></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_data_callback.html">AudioStreamDataCallback</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_audio_stream_error_callback.html">AudioStreamErrorCallback</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_default_stream_values.html">DefaultStreamValues</a></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structoboe_1_1_frame_timestamp.html">FrameTimestamp</a></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_latency_tuner.html">LatencyTuner</a></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_oboe_globals.html">OboeGlobals</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_result_with_value.html">ResultWithValue</a></td></tr>
 <tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classoboe_1_1_stabilized_callback.html">StabilizedCallback</a></td></tr>
@@ -274,6 +280,10 @@
 <tr class="memitem:af65aaea3c5d82eee6906664d61c094b3"><td class="memTemplParams" colspan="2">template&lt;typename FromType &gt; </td></tr>
 <tr class="memitem:af65aaea3c5d82eee6906664d61c094b3"><td class="memTemplItemLeft" align="right" valign="top">const char *&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceoboe.html#af65aaea3c5d82eee6906664d61c094b3">convertToText</a> (FromType input)</td></tr>
 <tr class="separator:af65aaea3c5d82eee6906664d61c094b3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a1ff1f1323d722494dac353a6b4d1bd5b"><td class="memItemLeft" align="right" valign="top">std::string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b">getPropertyString</a> (const char *name)</td></tr>
+<tr class="separator:a1ff1f1323d722494dac353a6b4d1bd5b"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a4284cffcf4d852ca4f357429303d7af5"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5">getPropertyInteger</a> (const char *name, int defaultValue)</td></tr>
+<tr class="separator:a4284cffcf4d852ca4f357429303d7af5"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a54528938e9fccab7ad8947ccf0e409db"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db">getSdkVersion</a> ()</td></tr>
 <tr class="separator:a54528938e9fccab7ad8947ccf0e409db"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a78417a797f5306478c8a37cee53fd12a"><td class="memItemLeft" align="right" valign="top"><a id="a78417a797f5306478c8a37cee53fd12a"></a>
@@ -854,6 +864,67 @@
 
 </div>
 </div>
+<a id="a4284cffcf4d852ca4f357429303d7af5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a4284cffcf4d852ca4f357429303d7af5">&#9670;&nbsp;</a></span>getPropertyInteger()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">int oboe::getPropertyInteger </td>
+          <td>(</td>
+          <td class="paramtype">const char *&#160;</td>
+          <td class="paramname"><em>name</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>defaultValue</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">name</td><td></td></tr>
+    <tr><td class="paramname">defaultValue</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>integer value associated with a property or the default value </dd></dl>
+
+</div>
+</div>
+<a id="a1ff1f1323d722494dac353a6b4d1bd5b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a1ff1f1323d722494dac353a6b4d1bd5b">&#9670;&nbsp;</a></span>getPropertyString()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">std::string oboe::getPropertyString </td>
+          <td>(</td>
+          <td class="paramtype">const char *&#160;</td>
+          <td class="paramname"><em>name</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">name</td><td></td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>the value of a named system property in a string or empty string </dd></dl>
+
+</div>
+</div>
 <a id="a54528938e9fccab7ad8947ccf0e409db"></a>
 <h2 class="memtitle"><span class="permalink"><a href="#a54528938e9fccab7ad8947ccf0e409db">&#9670;&nbsp;</a></span>getSdkVersion()</h2>
 
diff --git a/docs/reference/namespaces.html b/docs/reference/namespaces.html
index 059d764..860d475 100644
--- a/docs/reference/namespaces.html
+++ b/docs/reference/namespaces.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/pages.html b/docs/reference/pages.html
index 182d5b5..a0c44c4 100644
--- a/docs/reference/pages.html
+++ b/docs/reference/pages.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/search/all_0.js b/docs/reference/search/all_0.js
index e151f87..8347df5 100644
--- a/docs/reference/search/all_0.js
+++ b/docs/reference/search/all_0.js
@@ -13,5 +13,7 @@
   ['audiostreambase',['AudioStreamBase',['../classoboe_1_1_audio_stream_base.html',1,'oboe::AudioStreamBase'],['../classoboe_1_1_audio_stream_base.html#aa6b103e1b0f808bbc4949d56f0829f98',1,'oboe::AudioStreamBase::AudioStreamBase()']]],
   ['audiostreambuilder',['AudioStreamBuilder',['../classoboe_1_1_audio_stream_builder.html',1,'oboe']]],
   ['audiostreamcallback',['AudioStreamCallback',['../classoboe_1_1_audio_stream_callback.html',1,'oboe']]],
+  ['audiostreamdatacallback',['AudioStreamDataCallback',['../classoboe_1_1_audio_stream_data_callback.html',1,'oboe']]],
+  ['audiostreamerrorcallback',['AudioStreamErrorCallback',['../classoboe_1_1_audio_stream_error_callback.html',1,'oboe']]],
   ['api_20reference',['API reference',['../index.html',1,'']]]
 ];
diff --git a/docs/reference/search/all_6.js b/docs/reference/search/all_6.js
index ad683db..ce9595c 100644
--- a/docs/reference/search/all_6.js
+++ b/docs/reference/search/all_6.js
@@ -8,18 +8,23 @@
   ['getbuffersizeinframes',['getBufferSizeInFrames',['../classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b',1,'oboe::AudioStreamBase']]],
   ['getbytesperframe',['getBytesPerFrame',['../classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc',1,'oboe::AudioStream']]],
   ['getbytespersample',['getBytesPerSample',['../classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62',1,'oboe::AudioStream']]],
-  ['getcallback',['getCallback',['../classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797',1,'oboe::AudioStreamBase']]],
   ['getchannelcount',['getChannelCount',['../classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575',1,'oboe::AudioStreamBase']]],
   ['getcontenttype',['getContentType',['../classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82',1,'oboe::AudioStreamBase']]],
+  ['getdatacallback',['getDataCallback',['../classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c',1,'oboe::AudioStreamBase']]],
   ['getdeviceid',['getDeviceId',['../classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21',1,'oboe::AudioStreamBase']]],
   ['getdirection',['getDirection',['../classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1',1,'oboe::AudioStreamBase']]],
+  ['geterrorcallback',['getErrorCallback',['../classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0',1,'oboe::AudioStreamBase']]],
   ['getformat',['getFormat',['../classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86',1,'oboe::AudioStreamBase']]],
   ['getframesperburst',['getFramesPerBurst',['../classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a',1,'oboe::AudioStream']]],
   ['getframespercallback',['getFramesPerCallback',['../classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086',1,'oboe::AudioStreamBase']]],
+  ['getframesperdatacallback',['getFramesPerDataCallback',['../classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38',1,'oboe::AudioStreamBase']]],
   ['getframesread',['getFramesRead',['../classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df',1,'oboe::AudioStream']]],
   ['getframeswritten',['getFramesWritten',['../classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341',1,'oboe::AudioStream']]],
   ['getinputpreset',['getInputPreset',['../classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a',1,'oboe::AudioStreamBase']]],
+  ['getlasterrorcallbackresult',['getLastErrorCallbackResult',['../classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75',1,'oboe::AudioStream']]],
   ['getperformancemode',['getPerformanceMode',['../classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc',1,'oboe::AudioStreamBase']]],
+  ['getpropertyinteger',['getPropertyInteger',['../namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5',1,'oboe']]],
+  ['getpropertystring',['getPropertyString',['../namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b',1,'oboe']]],
   ['getsamplerate',['getSampleRate',['../classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087',1,'oboe::AudioStreamBase']]],
   ['getsamplerateconversionquality',['getSampleRateConversionQuality',['../classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2',1,'oboe::AudioStreamBase']]],
   ['getsdkversion',['getSdkVersion',['../namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db',1,'oboe']]],
diff --git a/docs/reference/search/all_7.js b/docs/reference/search/all_7.js
index 93086e0..f8e2e06 100644
--- a/docs/reference/search/all_7.js
+++ b/docs/reference/search/all_7.js
@@ -9,6 +9,9 @@
   ['isatmaximumbuffersize',['isAtMaximumBufferSize',['../classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4',1,'oboe::LatencyTuner']]],
   ['ischannelconversionallowed',['isChannelConversionAllowed',['../classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495',1,'oboe::AudioStreamBase']]],
   ['isdatacallbackenabled',['isDataCallbackEnabled',['../classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831',1,'oboe::AudioStream']]],
+  ['isdatacallbackspecified',['isDataCallbackSpecified',['../classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73',1,'oboe::AudioStreamBase']]],
+  ['iserrorcallbackspecified',['isErrorCallbackSpecified',['../classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3',1,'oboe::AudioStreamBase']]],
   ['isformatconversionallowed',['isFormatConversionAllowed',['../classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4',1,'oboe::AudioStreamBase']]],
+  ['isvalidconfig',['isValidConfig',['../classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2',1,'oboe::AudioStreamBase']]],
   ['isxruncountsupported',['isXRunCountSupported',['../classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4',1,'oboe::AudioStream']]]
 ];
diff --git a/docs/reference/search/all_a.js b/docs/reference/search/all_a.js
index 285495f..30be357 100644
--- a/docs/reference/search/all_a.js
+++ b/docs/reference/search/all_a.js
@@ -5,9 +5,11 @@
   ['mbuffersizeinframes',['mBufferSizeInFrames',['../classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a',1,'oboe::AudioStreamBase']]],
   ['mchannelcount',['mChannelCount',['../classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206',1,'oboe::AudioStreamBase']]],
   ['mcontenttype',['mContentType',['../classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b',1,'oboe::AudioStreamBase']]],
+  ['mdatacallback',['mDataCallback',['../classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f',1,'oboe::AudioStreamBase']]],
   ['mdeviceid',['mDeviceId',['../classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8',1,'oboe::AudioStreamBase']]],
   ['mdirection',['mDirection',['../classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880',1,'oboe::AudioStreamBase']]],
   ['media',['Media',['../namespaceoboe.html#a104ee8396c173fefac429759ea3c21a0a3b563524fdb17b4a86590470d40bef74',1,'oboe']]],
+  ['merrorcallback',['mErrorCallback',['../classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b',1,'oboe::AudioStreamBase']]],
   ['mformat',['mFormat',['../classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09',1,'oboe::AudioStreamBase']]],
   ['mframesperburst',['mFramesPerBurst',['../classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e',1,'oboe::AudioStreamBase']]],
   ['mframespercallback',['mFramesPerCallback',['../classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899',1,'oboe::AudioStreamBase']]],
@@ -21,7 +23,6 @@
   ['msamplerate',['mSampleRate',['../classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea',1,'oboe::AudioStreamBase']]],
   ['msessionid',['mSessionId',['../classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737',1,'oboe::AudioStreamBase']]],
   ['msharingmode',['mSharingMode',['../classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473',1,'oboe::AudioStreamBase']]],
-  ['mstreamcallback',['mStreamCallback',['../classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4',1,'oboe::AudioStreamBase']]],
   ['musage',['mUsage',['../classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c',1,'oboe::AudioStreamBase']]],
   ['music',['Music',['../namespaceoboe.html#a2a3cec6f021c1a324df60273710c604bac156fcc7b29059305cef26f3904d4517',1,'oboe']]]
 ];
diff --git a/docs/reference/search/all_c.js b/docs/reference/search/all_c.js
index 2b6b0bf..dcdc687 100644
--- a/docs/reference/search/all_c.js
+++ b/docs/reference/search/all_c.js
@@ -1,14 +1,16 @@
 var searchData=
 [
   ['oboe',['oboe',['../namespaceoboe.html',1,'']]],
-  ['onaudioready',['onAudioReady',['../classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df',1,'oboe::AudioStreamCallback::onAudioReady()'],['../classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49',1,'oboe::StabilizedCallback::onAudioReady()']]],
+  ['oboeglobals',['OboeGlobals',['../classoboe_1_1_oboe_globals.html',1,'oboe']]],
+  ['onaudioready',['onAudioReady',['../classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d',1,'oboe::AudioStreamDataCallback::onAudioReady()'],['../classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49',1,'oboe::StabilizedCallback::onAudioReady()']]],
   ['ondefaultcallback',['onDefaultCallback',['../classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe',1,'oboe::AudioStream']]],
-  ['onerrorafterclose',['onErrorAfterClose',['../classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd',1,'oboe::AudioStreamCallback::onErrorAfterClose()'],['../classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4',1,'oboe::StabilizedCallback::onErrorAfterClose()']]],
-  ['onerrorbeforeclose',['onErrorBeforeClose',['../classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9',1,'oboe::AudioStreamCallback::onErrorBeforeClose()'],['../classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10',1,'oboe::StabilizedCallback::onErrorBeforeClose()']]],
+  ['onerror',['onError',['../classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3',1,'oboe::AudioStreamErrorCallback']]],
+  ['onerrorafterclose',['onErrorAfterClose',['../classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe',1,'oboe::AudioStreamErrorCallback::onErrorAfterClose()'],['../classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4',1,'oboe::StabilizedCallback::onErrorAfterClose()']]],
+  ['onerrorbeforeclose',['onErrorBeforeClose',['../classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0',1,'oboe::AudioStreamErrorCallback::onErrorBeforeClose()'],['../classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10',1,'oboe::StabilizedCallback::onErrorBeforeClose()']]],
   ['open',['open',['../classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6',1,'oboe::AudioStream']]],
   ['openmanagedstream',['openManagedStream',['../classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff',1,'oboe::AudioStreamBuilder']]],
   ['opensles',['OpenSLES',['../namespaceoboe.html#a92972414867c81d5974cb2ed7abefbf6a24e758ea9c1e842ef71cc8ff8b63fa9b',1,'oboe']]],
-  ['openstream',['openStream',['../classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074',1,'oboe::AudioStreamBuilder']]],
+  ['openstream',['openStream',['../classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074',1,'oboe::AudioStreamBuilder::openStream(AudioStream **stream)'],['../classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb',1,'oboe::AudioStreamBuilder::openStream(std::shared_ptr&lt; oboe::AudioStream &gt; &amp;stream)']]],
   ['operator_20_21',['operator !',['../classoboe_1_1_result_with_value.html#a6fb3c61c5716a045ba48dc5a5dfc8169',1,'oboe::ResultWithValue']]],
   ['operator_20bool',['operator bool',['../classoboe_1_1_result_with_value.html#ae32b1953b777af7d1d0c94862ca39986',1,'oboe::ResultWithValue']]],
   ['operator_20result',['operator Result',['../classoboe_1_1_result_with_value.html#af62107817c0bc76047e6b655a78504ba',1,'oboe::ResultWithValue']]],
diff --git a/docs/reference/search/all_f.js b/docs/reference/search/all_f.js
index 8eb77d1..fd423fd 100644
--- a/docs/reference/search/all_f.js
+++ b/docs/reference/search/all_f.js
@@ -5,24 +5,30 @@
   ['sessionid',['SessionId',['../namespaceoboe.html#a5752250c10e96179e3618d7f72937eaf',1,'oboe']]],
   ['setaudioapi',['setAudioApi',['../classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391',1,'oboe::AudioStreamBuilder']]],
   ['setbuffercapacityinframes',['setBufferCapacityInFrames',['../classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef',1,'oboe::AudioStreamBuilder']]],
+  ['setbuffersizeincrement',['setBufferSizeIncrement',['../classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db',1,'oboe::LatencyTuner']]],
   ['setbuffersizeinframes',['setBufferSizeInFrames',['../classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03',1,'oboe::AudioStream']]],
   ['setcallback',['setCallback',['../classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd',1,'oboe::AudioStreamBuilder']]],
   ['setchannelconversionallowed',['setChannelConversionAllowed',['../classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563',1,'oboe::AudioStreamBuilder']]],
   ['setchannelcount',['setChannelCount',['../classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7',1,'oboe::AudioStreamBuilder']]],
   ['setcontenttype',['setContentType',['../classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468',1,'oboe::AudioStreamBuilder']]],
+  ['setdatacallback',['setDataCallback',['../classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70',1,'oboe::AudioStreamBuilder']]],
   ['setdatacallbackenabled',['setDataCallbackEnabled',['../classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba',1,'oboe::AudioStream']]],
   ['setdeviceid',['setDeviceId',['../classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e',1,'oboe::AudioStreamBuilder']]],
   ['setdirection',['setDirection',['../classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c',1,'oboe::AudioStreamBuilder']]],
+  ['seterrorcallback',['setErrorCallback',['../classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567',1,'oboe::AudioStreamBuilder']]],
   ['setformat',['setFormat',['../classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515',1,'oboe::AudioStreamBuilder']]],
   ['setformatconversionallowed',['setFormatConversionAllowed',['../classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2',1,'oboe::AudioStreamBuilder']]],
   ['setframespercallback',['setFramesPerCallback',['../classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54',1,'oboe::AudioStreamBuilder']]],
+  ['setframesperdatacallback',['setFramesPerDataCallback',['../classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e',1,'oboe::AudioStreamBuilder']]],
   ['setinputpreset',['setInputPreset',['../classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0',1,'oboe::AudioStreamBuilder']]],
+  ['setminimumbuffersize',['setMinimumBufferSize',['../classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8',1,'oboe::LatencyTuner']]],
   ['setperformancemode',['setPerformanceMode',['../classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee',1,'oboe::AudioStreamBuilder']]],
   ['setsamplerate',['setSampleRate',['../classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d',1,'oboe::AudioStreamBuilder']]],
   ['setsamplerateconversionquality',['setSampleRateConversionQuality',['../classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027',1,'oboe::AudioStreamBuilder']]],
   ['setsessionid',['setSessionId',['../classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d',1,'oboe::AudioStreamBuilder']]],
   ['setsharingmode',['setSharingMode',['../classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654',1,'oboe::AudioStreamBuilder']]],
   ['setusage',['setUsage',['../classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a',1,'oboe::AudioStreamBuilder']]],
+  ['setworkaroundsenabled',['setWorkaroundsEnabled',['../classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b',1,'oboe::OboeGlobals']]],
   ['shared',['Shared',['../namespaceoboe.html#a8330247b25429953a08354f41834d520aa6156ea9d66fef24e87e841fbabf7cca',1,'oboe']]],
   ['sharingmode',['SharingMode',['../namespaceoboe.html#a8330247b25429953a08354f41834d520',1,'oboe']]],
   ['sonification',['Sonification',['../namespaceoboe.html#a2a3cec6f021c1a324df60273710c604ba0885eef555037e94a7cf39fe683c2799',1,'oboe']]],
diff --git a/docs/reference/search/classes_0.js b/docs/reference/search/classes_0.js
index dbc8d2a..2a04f01 100644
--- a/docs/reference/search/classes_0.js
+++ b/docs/reference/search/classes_0.js
@@ -3,5 +3,7 @@
   ['audiostream',['AudioStream',['../classoboe_1_1_audio_stream.html',1,'oboe']]],
   ['audiostreambase',['AudioStreamBase',['../classoboe_1_1_audio_stream_base.html',1,'oboe']]],
   ['audiostreambuilder',['AudioStreamBuilder',['../classoboe_1_1_audio_stream_builder.html',1,'oboe']]],
-  ['audiostreamcallback',['AudioStreamCallback',['../classoboe_1_1_audio_stream_callback.html',1,'oboe']]]
+  ['audiostreamcallback',['AudioStreamCallback',['../classoboe_1_1_audio_stream_callback.html',1,'oboe']]],
+  ['audiostreamdatacallback',['AudioStreamDataCallback',['../classoboe_1_1_audio_stream_data_callback.html',1,'oboe']]],
+  ['audiostreamerrorcallback',['AudioStreamErrorCallback',['../classoboe_1_1_audio_stream_error_callback.html',1,'oboe']]]
 ];
diff --git a/docs/reference/search/classes_4.js b/docs/reference/search/classes_4.js
index 991f31b..d1e1d90 100644
--- a/docs/reference/search/classes_4.js
+++ b/docs/reference/search/classes_4.js
@@ -1,4 +1,4 @@
 var searchData=
 [
-  ['resultwithvalue',['ResultWithValue',['../classoboe_1_1_result_with_value.html',1,'oboe']]]
+  ['oboeglobals',['OboeGlobals',['../classoboe_1_1_oboe_globals.html',1,'oboe']]]
 ];
diff --git a/docs/reference/search/classes_5.js b/docs/reference/search/classes_5.js
index 6a6692b..991f31b 100644
--- a/docs/reference/search/classes_5.js
+++ b/docs/reference/search/classes_5.js
@@ -1,5 +1,4 @@
 var searchData=
 [
-  ['stabilizedcallback',['StabilizedCallback',['../classoboe_1_1_stabilized_callback.html',1,'oboe']]],
-  ['streamdeleterfunctor',['StreamDeleterFunctor',['../structoboe_1_1_stream_deleter_functor.html',1,'oboe']]]
+  ['resultwithvalue',['ResultWithValue',['../classoboe_1_1_result_with_value.html',1,'oboe']]]
 ];
diff --git a/docs/reference/search/classes_6.js b/docs/reference/search/classes_6.js
index 8578da8..6a6692b 100644
--- a/docs/reference/search/classes_6.js
+++ b/docs/reference/search/classes_6.js
@@ -1,4 +1,5 @@
 var searchData=
 [
-  ['version',['Version',['../structoboe_1_1_version.html',1,'oboe']]]
+  ['stabilizedcallback',['StabilizedCallback',['../classoboe_1_1_stabilized_callback.html',1,'oboe']]],
+  ['streamdeleterfunctor',['StreamDeleterFunctor',['../structoboe_1_1_stream_deleter_functor.html',1,'oboe']]]
 ];
diff --git a/docs/reference/search/classes_7.html b/docs/reference/search/classes_7.html
new file mode 100644
index 0000000..794e394
--- /dev/null
+++ b/docs/reference/search/classes_7.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_7.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+/* @license-end */
+--></script>
+</div>
+</body>
+</html>
diff --git a/docs/reference/search/classes_7.js b/docs/reference/search/classes_7.js
new file mode 100644
index 0000000..8578da8
--- /dev/null
+++ b/docs/reference/search/classes_7.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['version',['Version',['../structoboe_1_1_version.html',1,'oboe']]]
+];
diff --git a/docs/reference/search/functions_4.js b/docs/reference/search/functions_4.js
index 9c9e593..eb44bb5 100644
--- a/docs/reference/search/functions_4.js
+++ b/docs/reference/search/functions_4.js
@@ -6,18 +6,23 @@
   ['getbuffersizeinframes',['getBufferSizeInFrames',['../classoboe_1_1_audio_stream_base.html#af5217ab05bfde0d7637024b599302d0b',1,'oboe::AudioStreamBase']]],
   ['getbytesperframe',['getBytesPerFrame',['../classoboe_1_1_audio_stream.html#a5c01907a59d5f89a5e4b819fe66b08bc',1,'oboe::AudioStream']]],
   ['getbytespersample',['getBytesPerSample',['../classoboe_1_1_audio_stream.html#a44dda61e6e948e49b68f87172f084d62',1,'oboe::AudioStream']]],
-  ['getcallback',['getCallback',['../classoboe_1_1_audio_stream_base.html#a1b4a2a191546708da657510c3cd6b797',1,'oboe::AudioStreamBase']]],
   ['getchannelcount',['getChannelCount',['../classoboe_1_1_audio_stream_base.html#a87e6bf37d6a2a5e983b8ca8d29aea575',1,'oboe::AudioStreamBase']]],
   ['getcontenttype',['getContentType',['../classoboe_1_1_audio_stream_base.html#ab12e2d068fa87e0553b01a400d96eb82',1,'oboe::AudioStreamBase']]],
+  ['getdatacallback',['getDataCallback',['../classoboe_1_1_audio_stream_base.html#a9fb2f34ae62dbda2c10e8513b754fa0c',1,'oboe::AudioStreamBase']]],
   ['getdeviceid',['getDeviceId',['../classoboe_1_1_audio_stream_base.html#a093057d625bc896864b959974c265f21',1,'oboe::AudioStreamBase']]],
   ['getdirection',['getDirection',['../classoboe_1_1_audio_stream_base.html#a6f86f2233a04c5a0b056f0c1c261f1b1',1,'oboe::AudioStreamBase']]],
+  ['geterrorcallback',['getErrorCallback',['../classoboe_1_1_audio_stream_base.html#a1328fb9288166ff325995ce1ea1867f0',1,'oboe::AudioStreamBase']]],
   ['getformat',['getFormat',['../classoboe_1_1_audio_stream_base.html#ab1e640461d7bf9d596decb913da7ac86',1,'oboe::AudioStreamBase']]],
   ['getframesperburst',['getFramesPerBurst',['../classoboe_1_1_audio_stream.html#ac160acb656515814fa6fdd157c131a0a',1,'oboe::AudioStream']]],
   ['getframespercallback',['getFramesPerCallback',['../classoboe_1_1_audio_stream_base.html#a8878a90949badbb5486cc2e022a57086',1,'oboe::AudioStreamBase']]],
+  ['getframesperdatacallback',['getFramesPerDataCallback',['../classoboe_1_1_audio_stream_base.html#abc3ee2815568b425d15a40e132aa8e38',1,'oboe::AudioStreamBase']]],
   ['getframesread',['getFramesRead',['../classoboe_1_1_audio_stream.html#aeebfc59abd978cd6dff07c16cfe266df',1,'oboe::AudioStream']]],
   ['getframeswritten',['getFramesWritten',['../classoboe_1_1_audio_stream.html#ab43dd4074e1de57bac1c3fd111430341',1,'oboe::AudioStream']]],
   ['getinputpreset',['getInputPreset',['../classoboe_1_1_audio_stream_base.html#a5c773b93b8aa38191c7199cab023428a',1,'oboe::AudioStreamBase']]],
+  ['getlasterrorcallbackresult',['getLastErrorCallbackResult',['../classoboe_1_1_audio_stream.html#a8fe8afdf164a1fe835c514f709743d75',1,'oboe::AudioStream']]],
   ['getperformancemode',['getPerformanceMode',['../classoboe_1_1_audio_stream_base.html#a2ddb935de0e24dd7ae8e2cfbecac9fdc',1,'oboe::AudioStreamBase']]],
+  ['getpropertyinteger',['getPropertyInteger',['../namespaceoboe.html#a4284cffcf4d852ca4f357429303d7af5',1,'oboe']]],
+  ['getpropertystring',['getPropertyString',['../namespaceoboe.html#a1ff1f1323d722494dac353a6b4d1bd5b',1,'oboe']]],
   ['getsamplerate',['getSampleRate',['../classoboe_1_1_audio_stream_base.html#ae9d32f3e09174bad69e74f147ee33087',1,'oboe::AudioStreamBase']]],
   ['getsamplerateconversionquality',['getSampleRateConversionQuality',['../classoboe_1_1_audio_stream_base.html#a1de8d6982d411a0cf50a32efba0ca3f2',1,'oboe::AudioStreamBase']]],
   ['getsdkversion',['getSdkVersion',['../namespaceoboe.html#a54528938e9fccab7ad8947ccf0e409db',1,'oboe']]],
diff --git a/docs/reference/search/functions_5.js b/docs/reference/search/functions_5.js
index 4cfa4d6..3d03906 100644
--- a/docs/reference/search/functions_5.js
+++ b/docs/reference/search/functions_5.js
@@ -5,6 +5,9 @@
   ['isatmaximumbuffersize',['isAtMaximumBufferSize',['../classoboe_1_1_latency_tuner.html#a45c013fd6787ad09d328385d6314c4d4',1,'oboe::LatencyTuner']]],
   ['ischannelconversionallowed',['isChannelConversionAllowed',['../classoboe_1_1_audio_stream_base.html#aa4ec3aa76e69350fbce6f00786211495',1,'oboe::AudioStreamBase']]],
   ['isdatacallbackenabled',['isDataCallbackEnabled',['../classoboe_1_1_audio_stream.html#add85011ba825f74931deeb92c5edf831',1,'oboe::AudioStream']]],
+  ['isdatacallbackspecified',['isDataCallbackSpecified',['../classoboe_1_1_audio_stream_base.html#a9a54d38b985a2eb12c6972104dc0ce73',1,'oboe::AudioStreamBase']]],
+  ['iserrorcallbackspecified',['isErrorCallbackSpecified',['../classoboe_1_1_audio_stream_base.html#aef579f6d1f779c89d051f0963f2976b3',1,'oboe::AudioStreamBase']]],
   ['isformatconversionallowed',['isFormatConversionAllowed',['../classoboe_1_1_audio_stream_base.html#ace3625a7332bf02a86818fdf63fcccb4',1,'oboe::AudioStreamBase']]],
+  ['isvalidconfig',['isValidConfig',['../classoboe_1_1_audio_stream_base.html#a5d5e07e98921d0193a5c0ccbe06f68c2',1,'oboe::AudioStreamBase']]],
   ['isxruncountsupported',['isXRunCountSupported',['../classoboe_1_1_audio_stream.html#a43d8a098440cde28f4ee8bedd6d107c4',1,'oboe::AudioStream']]]
 ];
diff --git a/docs/reference/search/functions_7.js b/docs/reference/search/functions_7.js
index ab211bf..d06a926 100644
--- a/docs/reference/search/functions_7.js
+++ b/docs/reference/search/functions_7.js
@@ -1,12 +1,13 @@
 var searchData=
 [
-  ['onaudioready',['onAudioReady',['../classoboe_1_1_audio_stream_callback.html#af3a7c44f0254abe6e5e5bb566e2317df',1,'oboe::AudioStreamCallback::onAudioReady()'],['../classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49',1,'oboe::StabilizedCallback::onAudioReady()']]],
+  ['onaudioready',['onAudioReady',['../classoboe_1_1_audio_stream_data_callback.html#ad8a3a9f609df5fd3a5d885cbe1b2204d',1,'oboe::AudioStreamDataCallback::onAudioReady()'],['../classoboe_1_1_stabilized_callback.html#ad447e12ebf732cf151655c1fbaf58a49',1,'oboe::StabilizedCallback::onAudioReady()']]],
   ['ondefaultcallback',['onDefaultCallback',['../classoboe_1_1_audio_stream.html#a0ea79e60f5a3d29fc5a1a116aba11dfe',1,'oboe::AudioStream']]],
-  ['onerrorafterclose',['onErrorAfterClose',['../classoboe_1_1_audio_stream_callback.html#a57a1b21efc764e8bbf8d92008a993bfd',1,'oboe::AudioStreamCallback::onErrorAfterClose()'],['../classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4',1,'oboe::StabilizedCallback::onErrorAfterClose()']]],
-  ['onerrorbeforeclose',['onErrorBeforeClose',['../classoboe_1_1_audio_stream_callback.html#a77ceb641f941164d7b4d4c51c9a888b9',1,'oboe::AudioStreamCallback::onErrorBeforeClose()'],['../classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10',1,'oboe::StabilizedCallback::onErrorBeforeClose()']]],
+  ['onerror',['onError',['../classoboe_1_1_audio_stream_error_callback.html#a5ad4b8936746ecbb2160a9389b117fc3',1,'oboe::AudioStreamErrorCallback']]],
+  ['onerrorafterclose',['onErrorAfterClose',['../classoboe_1_1_audio_stream_error_callback.html#a76bd3ef3e00396e10c21812003654cfe',1,'oboe::AudioStreamErrorCallback::onErrorAfterClose()'],['../classoboe_1_1_stabilized_callback.html#af7521da42c4b08a71e6102994f6f41f4',1,'oboe::StabilizedCallback::onErrorAfterClose()']]],
+  ['onerrorbeforeclose',['onErrorBeforeClose',['../classoboe_1_1_audio_stream_error_callback.html#a4eb1e4916b71d8231e97b19898bc9bf0',1,'oboe::AudioStreamErrorCallback::onErrorBeforeClose()'],['../classoboe_1_1_stabilized_callback.html#a7ec0e9fca3181962ab78716bcda83e10',1,'oboe::StabilizedCallback::onErrorBeforeClose()']]],
   ['open',['open',['../classoboe_1_1_audio_stream.html#a686c6ce8a29051c858fd1de386805dc6',1,'oboe::AudioStream']]],
   ['openmanagedstream',['openManagedStream',['../classoboe_1_1_audio_stream_builder.html#a7ab172a9be4fca2489aa5cbcc48c20ff',1,'oboe::AudioStreamBuilder']]],
-  ['openstream',['openStream',['../classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074',1,'oboe::AudioStreamBuilder']]],
+  ['openstream',['openStream',['../classoboe_1_1_audio_stream_builder.html#a86b94cfa47729bef2e04dce1a9086074',1,'oboe::AudioStreamBuilder::openStream(AudioStream **stream)'],['../classoboe_1_1_audio_stream_builder.html#a44b68216c48f8fb08a9e63178e0b0eeb',1,'oboe::AudioStreamBuilder::openStream(std::shared_ptr&lt; oboe::AudioStream &gt; &amp;stream)']]],
   ['operator_20_21',['operator !',['../classoboe_1_1_result_with_value.html#a6fb3c61c5716a045ba48dc5a5dfc8169',1,'oboe::ResultWithValue']]],
   ['operator_20bool',['operator bool',['../classoboe_1_1_result_with_value.html#ae32b1953b777af7d1d0c94862ca39986',1,'oboe::ResultWithValue']]],
   ['operator_20result',['operator Result',['../classoboe_1_1_result_with_value.html#af62107817c0bc76047e6b655a78504ba',1,'oboe::ResultWithValue']]],
diff --git a/docs/reference/search/functions_a.js b/docs/reference/search/functions_a.js
index 3ac8b86..ed9e410 100644
--- a/docs/reference/search/functions_a.js
+++ b/docs/reference/search/functions_a.js
@@ -2,24 +2,30 @@
 [
   ['setaudioapi',['setAudioApi',['../classoboe_1_1_audio_stream_builder.html#a38c6d6c5e718df1e3ac69daaac47c391',1,'oboe::AudioStreamBuilder']]],
   ['setbuffercapacityinframes',['setBufferCapacityInFrames',['../classoboe_1_1_audio_stream_builder.html#abaff480867af51ca0899bfa6fd7cc3ef',1,'oboe::AudioStreamBuilder']]],
+  ['setbuffersizeincrement',['setBufferSizeIncrement',['../classoboe_1_1_latency_tuner.html#a2684b30205126c8acd2f75d01cce05db',1,'oboe::LatencyTuner']]],
   ['setbuffersizeinframes',['setBufferSizeInFrames',['../classoboe_1_1_audio_stream.html#a06e3f9e133b3a75515e7793939d1cd03',1,'oboe::AudioStream']]],
   ['setcallback',['setCallback',['../classoboe_1_1_audio_stream_builder.html#a698cefa9af73bc97c020c004821fccbd',1,'oboe::AudioStreamBuilder']]],
   ['setchannelconversionallowed',['setChannelConversionAllowed',['../classoboe_1_1_audio_stream_builder.html#ad50f5d20cdf420d982bf499790cd3563',1,'oboe::AudioStreamBuilder']]],
   ['setchannelcount',['setChannelCount',['../classoboe_1_1_audio_stream_builder.html#a075d10291e1f998d90c2f73ef767b5a7',1,'oboe::AudioStreamBuilder']]],
   ['setcontenttype',['setContentType',['../classoboe_1_1_audio_stream_builder.html#a6a17bafc217c2b624179fbbf77fe4468',1,'oboe::AudioStreamBuilder']]],
+  ['setdatacallback',['setDataCallback',['../classoboe_1_1_audio_stream_builder.html#acad307720e0f370267b4e2f9a626ae70',1,'oboe::AudioStreamBuilder']]],
   ['setdatacallbackenabled',['setDataCallbackEnabled',['../classoboe_1_1_audio_stream.html#a0faa6d3a6fd4f367e6f80d5a29e6dcba',1,'oboe::AudioStream']]],
   ['setdeviceid',['setDeviceId',['../classoboe_1_1_audio_stream_builder.html#af36ddcd00686a9e1de661bdac0685a8e',1,'oboe::AudioStreamBuilder']]],
   ['setdirection',['setDirection',['../classoboe_1_1_audio_stream_builder.html#ab3fbd47b06197619c26393637e26354c',1,'oboe::AudioStreamBuilder']]],
+  ['seterrorcallback',['setErrorCallback',['../classoboe_1_1_audio_stream_builder.html#aacb66f530bfc6f545911b5e169774567',1,'oboe::AudioStreamBuilder']]],
   ['setformat',['setFormat',['../classoboe_1_1_audio_stream_builder.html#aa2e1d2d73cd6c2eb9f349bf2fe5f6515',1,'oboe::AudioStreamBuilder']]],
   ['setformatconversionallowed',['setFormatConversionAllowed',['../classoboe_1_1_audio_stream_builder.html#a7ec5f427cd6fe55cb1ce536ff0cbb4d2',1,'oboe::AudioStreamBuilder']]],
   ['setframespercallback',['setFramesPerCallback',['../classoboe_1_1_audio_stream_builder.html#a3f397821f61eabaeedaf31064c859a54',1,'oboe::AudioStreamBuilder']]],
+  ['setframesperdatacallback',['setFramesPerDataCallback',['../classoboe_1_1_audio_stream_builder.html#afb8e95e80df7edd1af27af490438785e',1,'oboe::AudioStreamBuilder']]],
   ['setinputpreset',['setInputPreset',['../classoboe_1_1_audio_stream_builder.html#a144a3d095fd668210282f1a91f23e1f0',1,'oboe::AudioStreamBuilder']]],
+  ['setminimumbuffersize',['setMinimumBufferSize',['../classoboe_1_1_latency_tuner.html#adc96aa53b18a051b6ccdacb838139bf8',1,'oboe::LatencyTuner']]],
   ['setperformancemode',['setPerformanceMode',['../classoboe_1_1_audio_stream_builder.html#a6cd1d65612e844e59da71a68ea0ab3ee',1,'oboe::AudioStreamBuilder']]],
   ['setsamplerate',['setSampleRate',['../classoboe_1_1_audio_stream_builder.html#a30ef3d5f51d56a9f980dc09600ed139d',1,'oboe::AudioStreamBuilder']]],
   ['setsamplerateconversionquality',['setSampleRateConversionQuality',['../classoboe_1_1_audio_stream_builder.html#af7d24a9ec975d430732151e5ee0d1027',1,'oboe::AudioStreamBuilder']]],
   ['setsessionid',['setSessionId',['../classoboe_1_1_audio_stream_builder.html#a54c1651bdbe089d0d714af499e8a5f1d',1,'oboe::AudioStreamBuilder']]],
   ['setsharingmode',['setSharingMode',['../classoboe_1_1_audio_stream_builder.html#a3e991742acbbfb6fe5ebcf592c478654',1,'oboe::AudioStreamBuilder']]],
   ['setusage',['setUsage',['../classoboe_1_1_audio_stream_builder.html#a593255a2f5eb972665775cfc5bc58f6a',1,'oboe::AudioStreamBuilder']]],
+  ['setworkaroundsenabled',['setWorkaroundsEnabled',['../classoboe_1_1_oboe_globals.html#af2b8af764c5a5e6fc007b7725117303b',1,'oboe::OboeGlobals']]],
   ['start',['start',['../classoboe_1_1_audio_stream.html#af04f03eb6b64b564f1c4401688987d21',1,'oboe::AudioStream']]],
   ['stop',['stop',['../classoboe_1_1_audio_stream.html#aec093859d42f0470c884edd1e976d9f3',1,'oboe::AudioStream']]]
 ];
diff --git a/docs/reference/search/searchdata.js b/docs/reference/search/searchdata.js
index 9af729f..cee1bb6 100644
--- a/docs/reference/search/searchdata.js
+++ b/docs/reference/search/searchdata.js
@@ -1,7 +1,7 @@
 var indexSectionsWithContent =
 {
   0: "abcdefgiklmnoprstuvw",
-  1: "adflrsv",
+  1: "adflorsv",
   2: "o",
   3: "acefgiloprstuvw",
   4: "cfkmnpst",
diff --git a/docs/reference/search/variables_3.js b/docs/reference/search/variables_3.js
index 7739940..1f4218c 100644
--- a/docs/reference/search/variables_3.js
+++ b/docs/reference/search/variables_3.js
@@ -5,8 +5,10 @@
   ['mbuffersizeinframes',['mBufferSizeInFrames',['../classoboe_1_1_audio_stream_base.html#a3b65595d26d1eae1b8ce9925a5b98f6a',1,'oboe::AudioStreamBase']]],
   ['mchannelcount',['mChannelCount',['../classoboe_1_1_audio_stream_base.html#a5ff460bac9d14dfeac4eeddfcbb6e206',1,'oboe::AudioStreamBase']]],
   ['mcontenttype',['mContentType',['../classoboe_1_1_audio_stream_base.html#a5f8f0e5add381b841856de80ea4cdb2b',1,'oboe::AudioStreamBase']]],
+  ['mdatacallback',['mDataCallback',['../classoboe_1_1_audio_stream_base.html#a6d8493f66a945cb426506c70f0358e5f',1,'oboe::AudioStreamBase']]],
   ['mdeviceid',['mDeviceId',['../classoboe_1_1_audio_stream_base.html#a23dafa12fb1a6242b088ebd5a52798c8',1,'oboe::AudioStreamBase']]],
   ['mdirection',['mDirection',['../classoboe_1_1_audio_stream_base.html#a26e9294721561d3b16bcaeec5faf4880',1,'oboe::AudioStreamBase']]],
+  ['merrorcallback',['mErrorCallback',['../classoboe_1_1_audio_stream_base.html#adc0c8cc54adb6d3350c62b8a74b9c57b',1,'oboe::AudioStreamBase']]],
   ['mformat',['mFormat',['../classoboe_1_1_audio_stream_base.html#a7869f04836c2c2bdc10c7309ad4b8e09',1,'oboe::AudioStreamBase']]],
   ['mframesperburst',['mFramesPerBurst',['../classoboe_1_1_audio_stream_base.html#a54061319ed348329a29d883a5de2482e',1,'oboe::AudioStreamBase']]],
   ['mframespercallback',['mFramesPerCallback',['../classoboe_1_1_audio_stream_base.html#a3962eb94420ad0ecea70029236001899',1,'oboe::AudioStreamBase']]],
@@ -18,6 +20,5 @@
   ['msamplerate',['mSampleRate',['../classoboe_1_1_audio_stream_base.html#a998885bb6c4f37e145f4626ad4177dea',1,'oboe::AudioStreamBase']]],
   ['msessionid',['mSessionId',['../classoboe_1_1_audio_stream_base.html#abe1c1e9cada1ced9b5c1504ac9b07737',1,'oboe::AudioStreamBase']]],
   ['msharingmode',['mSharingMode',['../classoboe_1_1_audio_stream_base.html#ae9187492b679c97a0963e264954be473',1,'oboe::AudioStreamBase']]],
-  ['mstreamcallback',['mStreamCallback',['../classoboe_1_1_audio_stream_base.html#ae3f72318212dd9977d7fa0ced92c91f4',1,'oboe::AudioStreamBase']]],
   ['musage',['mUsage',['../classoboe_1_1_audio_stream_base.html#a5b518e82f39c9fcbd7050fd66adb253c',1,'oboe::AudioStreamBase']]]
 ];
diff --git a/docs/reference/structoboe_1_1_frame_timestamp-members.html b/docs/reference/structoboe_1_1_frame_timestamp-members.html
index 23e92af..65258b7 100644
--- a/docs/reference/structoboe_1_1_frame_timestamp-members.html
+++ b/docs/reference/structoboe_1_1_frame_timestamp-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/structoboe_1_1_frame_timestamp.html b/docs/reference/structoboe_1_1_frame_timestamp.html
index 88cf8b4..fd8e1f4 100644
--- a/docs/reference/structoboe_1_1_frame_timestamp.html
+++ b/docs/reference/structoboe_1_1_frame_timestamp.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/structoboe_1_1_stream_deleter_functor-members.html b/docs/reference/structoboe_1_1_stream_deleter_functor-members.html
index e99d8b3..dec5ee1 100644
--- a/docs/reference/structoboe_1_1_stream_deleter_functor-members.html
+++ b/docs/reference/structoboe_1_1_stream_deleter_functor-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/structoboe_1_1_stream_deleter_functor.html b/docs/reference/structoboe_1_1_stream_deleter_functor.html
index bffff5f..1fa0714 100644
--- a/docs/reference/structoboe_1_1_stream_deleter_functor.html
+++ b/docs/reference/structoboe_1_1_stream_deleter_functor.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
@@ -84,7 +84,7 @@
 <tr class="separator:aa63f56f03cbdc07e52159c99c7a005be"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<div class="textblock"><p>This struct is a stateless functor which closes a audiostream prior to its deletion. This means it can be used to safely delete a smart pointer referring to an open stream. </p>
+<div class="textblock"><p>This struct is a stateless functor which closes an <a class="el" href="classoboe_1_1_audio_stream.html">AudioStream</a> prior to its deletion. This means it can be used to safely delete a smart pointer referring to an open stream. </p>
 </div><hr/>The documentation for this struct was generated from the following file:<ul>
 <li>include/oboe/<a class="el" href="_audio_stream_8h_source.html">AudioStream.h</a></li>
 </ul>
diff --git a/docs/reference/structoboe_1_1_version-members.html b/docs/reference/structoboe_1_1_version-members.html
index 6f78544..fd09739 100644
--- a/docs/reference/structoboe_1_1_version-members.html
+++ b/docs/reference/structoboe_1_1_version-members.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/docs/reference/structoboe_1_1_version.html b/docs/reference/structoboe_1_1_version.html
index 6dddbf6..fe7af0b 100644
--- a/docs/reference/structoboe_1_1_version.html
+++ b/docs/reference/structoboe_1_1_version.html
@@ -22,7 +22,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">Oboe
-   &#160;<span id="projectnumber">1.2</span>
+   &#160;<span id="projectnumber">1.5</span>
    </div>
    <div id="projectbrief">A library for creating real-time audio apps on Android</div>
   </td>
diff --git a/include/oboe/AudioStream.h b/include/oboe/AudioStream.h
index a158aaf..c862de6 100644
--- a/include/oboe/AudioStream.h
+++ b/include/oboe/AudioStream.h
@@ -393,12 +393,25 @@
      * Swap old callback for new callback.
      * This not atomic.
      * This should only be used internally.
-     * @param streamCallback
-     * @return previous streamCallback
+     * @param dataCallback
+     * @return previous dataCallback
      */
-    AudioStreamCallback *swapCallback(AudioStreamCallback *streamCallback) {
-        AudioStreamCallback *previousCallback = mStreamCallback;
-        mStreamCallback = streamCallback;
+    AudioStreamDataCallback *swapDataCallback(AudioStreamDataCallback *dataCallback) {
+        AudioStreamDataCallback *previousCallback = mDataCallback;
+        mDataCallback = dataCallback;
+        return previousCallback;
+    }
+
+    /*
+     * Swap old callback for new callback.
+     * This not atomic.
+     * This should only be used internally.
+     * @param errorCallback
+     * @return previous errorCallback
+     */
+    AudioStreamErrorCallback *swapErrorCallback(AudioStreamErrorCallback *errorCallback) {
+        AudioStreamErrorCallback *previousCallback = mErrorCallback;
+        mErrorCallback = errorCallback;
         return previousCallback;
     }
 
@@ -419,6 +432,13 @@
     ResultWithValue<int32_t> waitForAvailableFrames(int32_t numFrames,
                                                     int64_t timeoutNanoseconds);
 
+    /**
+     * @return last result passed from an error callback
+     */
+    virtual oboe::Result getLastErrorCallbackResult() const {
+        return mErrorCallbackResult;
+    }
+
 protected:
 
     /**
@@ -515,8 +535,10 @@
 
     std::mutex           mLock; // for synchronizing start/stop/close
 
+    oboe::Result         mErrorCallbackResult = oboe::Result::OK;
 
 private:
+
     // Log the scheduler if it changes.
     void                 checkScheduler();
     int                  mPreviousScheduler = -1;
diff --git a/include/oboe/AudioStreamBase.h b/include/oboe/AudioStreamBase.h
index 787ff20..d431767 100644
--- a/include/oboe/AudioStreamBase.h
+++ b/include/oboe/AudioStreamBase.h
@@ -62,9 +62,14 @@
     int32_t getSampleRate() const { return mSampleRate; }
 
     /**
-     * @return the number of frames in each callback or kUnspecified.
+     * @deprecated use `getFramesPerDataCallback` instead.
      */
-    int32_t getFramesPerCallback() const { return mFramesPerCallback; }
+    int32_t getFramesPerCallback() const { return getFramesPerDataCallback(); }
+
+    /**
+     * @return the number of frames in each data callback or kUnspecified.
+     */
+    int32_t getFramesPerDataCallback() const { return mFramesPerCallback; }
 
     /**
      * @return the audio sample format (e.g. Float or I16)
@@ -100,10 +105,35 @@
     int32_t getDeviceId() const { return mDeviceId; }
 
     /**
-     * @return the callback object for this stream, if set.
+     * For internal use only.
+     * @return the data callback object for this stream, if set.
      */
-    AudioStreamCallback* getCallback() const {
-        return mStreamCallback;
+    AudioStreamDataCallback *getDataCallback() const {
+        return mDataCallback;
+    }
+
+    /**
+     * For internal use only.
+     * @return the error callback object for this stream, if set.
+     */
+    AudioStreamErrorCallback *getErrorCallback() const {
+        return mErrorCallback;
+    }
+
+    /**
+     * @return true if a data callback was set for this stream
+     */
+    bool isDataCallbackSpecified() const {
+        return mDataCallback != nullptr;
+    }
+
+    /**
+     * Note that if the app does not set an error callback then a
+     * default one may be provided.
+     * @return true if an error callback was set for this stream
+     */
+    bool isErrorCallbackSpecified() const {
+        return mErrorCallback != nullptr;
     }
 
     /**
@@ -148,9 +178,12 @@
     }
 
 protected:
+    /** The callback which will be fired when new data is ready to be read/written. **/
+    AudioStreamDataCallback        *mDataCallback = nullptr;
 
-    /** The callback which will be fired when new data is ready to be read/written **/
-    AudioStreamCallback            *mStreamCallback = nullptr;
+    /** The callback which will be fired when an error or a disconnect occurs. **/
+    AudioStreamErrorCallback       *mErrorCallback = nullptr;
+
     /** Number of audio frames which will be requested in each callback */
     int32_t                         mFramesPerCallback = kUnspecified;
     /** Stream channel count */
diff --git a/include/oboe/AudioStreamBuilder.h b/include/oboe/AudioStreamBuilder.h
index 80c5da4..de9c606 100644
--- a/include/oboe/AudioStreamBuilder.h
+++ b/include/oboe/AudioStreamBuilder.h
@@ -75,6 +75,13 @@
     }
 
     /**
+     * @deprecated use `setFramesPerDataCallback` instead.
+     */
+    AudioStreamBuilder *setFramesPerCallback(int framesPerCallback) {
+        return setFramesPerDataCallback(framesPerCallback);
+    }
+
+    /**
      * Request a specific number of frames for the data callback.
      *
      * Default is kUnspecified. If the value is unspecified then
@@ -88,7 +95,7 @@
      * @param framesPerCallback
      * @return pointer to the builder so calls can be chained
      */
-    AudioStreamBuilder *setFramesPerCallback(int framesPerCallback) {
+    AudioStreamBuilder *setFramesPerDataCallback(int framesPerCallback) {
         mFramesPerCallback = framesPerCallback;
         return this;
     }
@@ -306,8 +313,44 @@
     }
 
     /**
+     * Specifies an object to handle data related callbacks from the underlying API.
+     *
+     * <strong>Important: See AudioStreamCallback for restrictions on what may be called
+     * from the callback methods.</strong>
+     *
+     * @param dataCallback
+     * @return pointer to the builder so calls can be chained
+     */
+    AudioStreamBuilder *setDataCallback(oboe::AudioStreamDataCallback *dataCallback) {
+        mDataCallback = dataCallback;
+        return this;
+    }
+
+    /**
+     * Specifies an object to handle error related callbacks from the underlying API.
+     * This can occur when a stream is disconnected because a headset is plugged in or unplugged.
+     * It can also occur if the audio service fails or if an exclusive stream is stolen by
+     * another stream.
+     *
+     * <strong>Important: See AudioStreamCallback for restrictions on what may be called
+     * from the callback methods.</strong>
+     *
+     * <strong>When an error callback occurs, the associated stream must be stopped and closed
+     * in a separate thread.</strong>
+     *
+     * @param errorCallback
+     * @return pointer to the builder so calls can be chained
+     */
+    AudioStreamBuilder *setErrorCallback(oboe::AudioStreamErrorCallback *errorCallback) {
+        mErrorCallback = errorCallback;
+        return this;
+    }
+
+    /**
      * Specifies an object to handle data or error related callbacks from the underlying API.
      *
+     * This is the equivalent of calling both setDataCallback() and setErrorCallback().
+     *
      * <strong>Important: See AudioStreamCallback for restrictions on what may be called
      * from the callback methods.</strong>
      *
@@ -327,7 +370,9 @@
      * @return pointer to the builder so calls can be chained
      */
     AudioStreamBuilder *setCallback(AudioStreamCallback *streamCallback) {
-        mStreamCallback = streamCallback;
+        // Use the same callback object for both, dual inheritance.
+        mDataCallback = streamCallback;
+        mErrorCallback = streamCallback;
         return this;
     }
 
diff --git a/include/oboe/AudioStreamCallback.h b/include/oboe/AudioStreamCallback.h
index f427693..915c3d7 100644
--- a/include/oboe/AudioStreamCallback.h
+++ b/include/oboe/AudioStreamCallback.h
@@ -24,15 +24,16 @@
 class AudioStream;
 
 /**
- * AudioStreamCallback defines a callback interface for:
- *
- * 1) moving data to/from an audio stream using `onAudioReady`
+ * AudioStreamDataCallback defines a callback interface for
+ * moving data to/from an audio stream using `onAudioReady`
  * 2) being alerted when a stream has an error using `onError*` methods
  *
+ * It is used with AudioStreamBuilder::setDataCallback().
  */
-class AudioStreamCallback {
+
+class AudioStreamDataCallback {
 public:
-    virtual ~AudioStreamCallback() = default;
+    virtual ~AudioStreamDataCallback() = default;
 
     /**
      * A buffer is ready for processing.
@@ -75,21 +76,64 @@
      * If you need to move data, eg. MIDI commands, in or out of the callback function then
      * we recommend the use of non-blocking techniques such as an atomic FIFO.
      *
-     * @param oboeStream pointer to the associated stream
+     * @param audioStream pointer to the associated stream
      * @param audioData buffer containing input data or a place to put output data
      * @param numFrames number of frames to be processed
      * @return DataCallbackResult::Continue or DataCallbackResult::Stop
      */
     virtual DataCallbackResult onAudioReady(
-            AudioStream *oboeStream,
+            AudioStream *audioStream,
             void *audioData,
             int32_t numFrames) = 0;
+};
+
+/**
+ * AudioStreamErrorCallback defines a callback interface for
+ * being alerted when a stream has an error or is disconnected
+ * using `onError*` methods.
+ *
+ * It is used with AudioStreamBuilder::setErrorCallback().
+ */
+class AudioStreamErrorCallback {
+public:
+    virtual ~AudioStreamErrorCallback() = default;
 
     /**
-     * This will be called when an error occurs on a stream or when the stream is disconnected.
+     * This will be called before other `onError` methods when an error occurs on a stream,
+     * such as when the stream is disconnected.
      *
-     * Note that this will be called on a different thread than the onAudioReady() thread.
-     * This thread will be created by Oboe.
+     * It can be used to override and customize the normal error processing.
+     * Use of this method is considered an advanced technique.
+     * It might, for example, be used if an app want to use a high level lock when
+     * closing and reopening a stream.
+     * Or it might be used when an app want to signal a management thread that handles
+     * all of the stream state.
+     *
+     * If this method returns false it indicates that the stream has *not been stopped and closed
+     * by the application. In this case it will be stopped by Oboe in the following way:
+     * onErrorBeforeClose() will be called, then the stream will be closed and onErrorAfterClose()
+     * will be closed.
+     *
+     * If this method returns true it indicates that the stream *has* been stopped and closed
+     * by the application and Oboe will not do this.
+     * In that case, the app MUST stop() and close() the stream.
+     *
+     * This method will be called on a thread created by Oboe.
+     *
+     * @param audioStream pointer to the associated stream
+     * @param error
+     * @return true if the stream has been stopped and closed, false if not
+     */
+    virtual bool onError(AudioStream* /* audioStream */, Result /* error */) {
+        return false;
+    }
+
+    /**
+     * This will be called when an error occurs on a stream,
+     * such as when the stream is disconnected,
+     * and if onError() returns false (indicating that the error has not already been handled).
+     *
+     * Note that this will be called on a thread created by Oboe.
      *
      * The underlying stream will already be stopped by Oboe but not yet closed.
      * So the stream can be queried.
@@ -97,27 +141,49 @@
      * Do not close or delete the stream in this method because it will be
      * closed after this method returns.
      *
-     * @param oboeStream pointer to the associated stream
+     * @param audioStream pointer to the associated stream
      * @param error
      */
-    virtual void onErrorBeforeClose(AudioStream* /* oboeStream */, Result /* error */) {}
+    virtual void onErrorBeforeClose(AudioStream* /* audioStream */, Result /* error */) {}
 
     /**
-     * This will be called when an error occurs on a stream or when the stream is disconnected.
+     * This will be called when an error occurs on a stream,
+     * such as when the stream is disconnected,
+     * and if onError() returns false (indicating that the error has not already been handled).
+     *
      * The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe.
      * So the underlying stream cannot be referenced.
      * But you can still query most parameters.
      *
      * This callback could be used to reopen a new stream on another device.
-     * You can safely delete the old AudioStream in this method.
      *
-     * @param oboeStream pointer to the associated stream
+     * @param audioStream pointer to the associated stream
      * @param error
      */
-    virtual void onErrorAfterClose(AudioStream* /* oboeStream */, Result /* error */) {}
+    virtual void onErrorAfterClose(AudioStream* /* audioStream */, Result /* error */) {}
 
 };
 
+/**
+ * AudioStreamCallback defines a callback interface for:
+ *
+ * 1) moving data to/from an audio stream using `onAudioReady`
+ * 2) being alerted when a stream has an error using `onError*` methods
+ *
+ * It is used with AudioStreamBuilder::setCallback().
+ *
+ * It combines the interfaces defined by AudioStreamDataCallback and AudioStreamErrorCallback.
+ * This was the original callback object. We now recommend using the individual interfaces
+ * and using setDataCallback() and setErrorCallback().
+ *
+ * @deprecated Use `AudioStreamDataCallback` and `AudioStreamErrorCallback` instead
+ */
+class AudioStreamCallback : public AudioStreamDataCallback,
+                            public AudioStreamErrorCallback {
+public:
+    virtual ~AudioStreamCallback() = default;
+};
+
 } // namespace oboe
 
 #endif //OBOE_STREAM_CALLBACK_H
diff --git a/include/oboe/Version.h b/include/oboe/Version.h
index 6d29672..fac42d4 100644
--- a/include/oboe/Version.h
+++ b/include/oboe/Version.h
@@ -34,10 +34,10 @@
 #define OBOE_VERSION_MAJOR 1
 
 // Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description.
-#define OBOE_VERSION_MINOR 4
+#define OBOE_VERSION_MINOR 5
 
 // Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.
-#define OBOE_VERSION_PATCH 3
+#define OBOE_VERSION_PATCH 0
 
 #define OBOE_STRINGIFY(x) #x
 #define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)
diff --git a/samples/LiveEffect/src/main/cpp/FullDuplexPass.h b/samples/LiveEffect/src/main/cpp/FullDuplexPass.h
index 11bdd45..9a250f8 100644
--- a/samples/LiveEffect/src/main/cpp/FullDuplexPass.h
+++ b/samples/LiveEffect/src/main/cpp/FullDuplexPass.h
@@ -16,19 +16,42 @@
 
 #ifndef SAMPLES_FULLDUPLEXPASS_H
 #define SAMPLES_FULLDUPLEXPASS_H
+
 #include "FullDuplexStream.h"
 
 class FullDuplexPass : public FullDuplexStream {
 public:
     virtual oboe::DataCallbackResult
-    onBothStreamsReady(const void *inputData, int numInputFrames, void *outputData,
-                       int numOutputFrames) {
-        size_t bytesPerFrame = this->getOutputStream()->getBytesPerFrame();
-        size_t bytesToWrite = numInputFrames * bytesPerFrame;
-        size_t byteDiff = (numOutputFrames - numInputFrames) * bytesPerFrame;
-        size_t bytesToZero = (byteDiff > 0) ? byteDiff : 0;
-        memcpy(outputData, inputData, bytesToWrite);
-        memset((u_char*) outputData + bytesToWrite, 0, bytesToZero);
+    onBothStreamsReady(
+            std::shared_ptr<oboe::AudioStream> inputStream,
+            const void *inputData,
+            int   numInputFrames,
+            std::shared_ptr<oboe::AudioStream> outputStream,
+            void *outputData,
+            int   numOutputFrames) {
+        // Copy the input samples to the output with a little arbitrary gain change.
+
+        // This code assumes the data format for both streams is Float.
+        const float *inputFloats = static_cast<const float *>(inputData);
+        float *outputFloats = static_cast<float *>(outputData);
+
+        // It also assumes the channel count for each stream is the same.
+        int32_t samplesPerFrame = outputStream->getChannelCount();
+        int32_t numInputSamples = numInputFrames * samplesPerFrame;
+        int32_t numOutputSamples = numInputFrames * samplesPerFrame;
+
+        // It is possible that there may be fewer input than output samples.
+        int32_t samplesToProcess = std::min(numInputSamples, numOutputSamples);
+        for (int32_t i = 0; i < samplesToProcess; i++) {
+            *outputFloats++ = *inputFloats++ * 0.95; // do some arbitrary processing
+        }
+
+        // If there are fewer input samples then clear the rest of the buffer.
+        int32_t samplesLeft = numOutputSamples - numInputSamples;
+        for (int32_t i = 0; i < samplesLeft; i++) {
+            *outputFloats++ = 0.0; // silence
+        }
+
         return oboe::DataCallbackResult::Continue;
     }
 };
diff --git a/samples/LiveEffect/src/main/cpp/FullDuplexStream.cpp b/samples/LiveEffect/src/main/cpp/FullDuplexStream.cpp
index 5b2fd41..e38bb5f 100644
--- a/samples/LiveEffect/src/main/cpp/FullDuplexStream.cpp
+++ b/samples/LiveEffect/src/main/cpp/FullDuplexStream.cpp
@@ -31,7 +31,7 @@
         // Drain the input.
         int32_t totalFramesRead = 0;
         do {
-            oboe::ResultWithValue<int32_t> result = getInputStream()->read(mInputBuffer.get(),
+            oboe::ResultWithValue<int32_t> result = mInputStream->read(mInputBuffer.get(),
                                                                            numFrames,
                                                                            0 /* timeout */);
             if (!result) {
@@ -52,7 +52,7 @@
 
     } else if (mCountCallbacksToDiscard > 0) {
         // Ignore. Allow the input to reach to equilibrium with the output.
-        oboe::ResultWithValue<int32_t> result = getInputStream()->read(mInputBuffer.get(),
+        oboe::ResultWithValue<int32_t> result = mInputStream->read(mInputBuffer.get(),
                                                                        numFrames,
                                                                        0 /* timeout */);
         if (!result) {
@@ -62,7 +62,7 @@
 
     } else {
         // Read data into input buffer.
-        oboe::ResultWithValue<int32_t> result = getInputStream()->read(mInputBuffer.get(),
+        oboe::ResultWithValue<int32_t> result = mInputStream->read(mInputBuffer.get(),
                                                                        numFrames,
                                                                        0 /* timeout */);
         if (!result) {
@@ -71,14 +71,14 @@
             int32_t framesRead = result.value();
 
             callbackResult = onBothStreamsReady(
-                    mInputBuffer.get(), framesRead,
-                    audioData, numFrames
+                    mInputStream, mInputBuffer.get(), framesRead,
+                    mOutputStream, audioData, numFrames
             );
         }
     }
 
     if (callbackResult == oboe::DataCallbackResult::Stop) {
-        getInputStream()->requestStop();
+        mInputStream->requestStop();
     }
 
     return callbackResult;
@@ -90,27 +90,27 @@
     mCountCallbacksToDiscard = kNumCallbacksToDiscard;
 
     // Determine maximum size that could possibly be called.
-    int32_t bufferSize = getOutputStream()->getBufferCapacityInFrames()
-            * getOutputStream()->getChannelCount();
+    int32_t bufferSize = mOutputStream->getBufferCapacityInFrames()
+            * mOutputStream->getChannelCount();
     if (bufferSize > mBufferSize) {
         mInputBuffer = std::make_unique<float[]>(bufferSize);
         mBufferSize = bufferSize;
     }
-    oboe::Result result = getInputStream()->requestStart();
+    oboe::Result result = mInputStream->requestStart();
     if (result != oboe::Result::OK) {
         return result;
     }
-    return getOutputStream()->requestStart();
+    return mOutputStream->requestStart();
 }
 
 oboe::Result FullDuplexStream::stop() {
     oboe::Result outputResult = oboe::Result::OK;
     oboe::Result inputResult = oboe::Result::OK;
-    if (getOutputStream()) {
-        outputResult = getOutputStream()->requestStop();
+    if (mOutputStream) {
+        outputResult = mOutputStream->requestStop();
     }
-    if (getInputStream()) {
-        inputResult = getInputStream()->requestStop();
+    if (mInputStream) {
+        inputResult = mInputStream->requestStop();
     }
     if (outputResult != oboe::Result::OK) {
         return outputResult;
diff --git a/samples/LiveEffect/src/main/cpp/FullDuplexStream.h b/samples/LiveEffect/src/main/cpp/FullDuplexStream.h
index 90fa63b..c30bc04 100644
--- a/samples/LiveEffect/src/main/cpp/FullDuplexStream.h
+++ b/samples/LiveEffect/src/main/cpp/FullDuplexStream.h
@@ -27,20 +27,13 @@
     FullDuplexStream() {}
     virtual ~FullDuplexStream() = default;
 
-    void setInputStream(oboe::AudioStream *stream) {
+    void setInputStream(std::shared_ptr<oboe::AudioStream> stream) {
         mInputStream = stream;
     }
 
-    oboe::AudioStream *getInputStream() {
-        return mInputStream;
-    }
-
-    void setOutputStream(oboe::AudioStream *stream) {
+    void setOutputStream(std::shared_ptr<oboe::AudioStream> stream) {
         mOutputStream = stream;
     }
-    oboe::AudioStream *getOutputStream() {
-        return mOutputStream;
-    }
 
     virtual oboe::Result start();
 
@@ -51,8 +44,10 @@
      * App should override this method.
      */
     virtual oboe::DataCallbackResult onBothStreamsReady(
+            std::shared_ptr<oboe::AudioStream> inputStream,
             const void *inputData,
             int   numInputFrames,
+            std::shared_ptr<oboe::AudioStream> outputStream,
             void *outputData,
             int   numOutputFrames
             ) = 0;
@@ -96,8 +91,8 @@
     // Discard some callbacks so the input and output reach equilibrium.
     int32_t              mCountCallbacksToDiscard = kNumCallbacksToDiscard;
 
-    oboe::AudioStream   *mInputStream = nullptr;
-    oboe::AudioStream   *mOutputStream = nullptr;
+    std::shared_ptr<oboe::AudioStream> mInputStream;
+    std::shared_ptr<oboe::AudioStream> mOutputStream;
 
     int32_t              mBufferSize = 0;
     std::unique_ptr<float[]> mInputBuffer;
diff --git a/samples/LiveEffect/src/main/cpp/LiveEffectEngine.cpp b/samples/LiveEffect/src/main/cpp/LiveEffectEngine.cpp
index 5ab4639..8c873f8 100644
--- a/samples/LiveEffect/src/main/cpp/LiveEffectEngine.cpp
+++ b/samples/LiveEffect/src/main/cpp/LiveEffectEngine.cpp
@@ -23,13 +23,6 @@
     assert(mOutputChannelCount == mInputChannelCount);
 }
 
-LiveEffectEngine::~LiveEffectEngine() {
-
-    mFullDuplexPass.stop();
-    closeStream(mPlayStream);
-    closeStream(mRecordingStream);
-}
-
 void LiveEffectEngine::setRecordingDeviceId(int32_t deviceId) {
     mRecordingDeviceId = deviceId;
 }
@@ -61,22 +54,29 @@
             }
         } else {
             mFullDuplexPass.stop();
-            /*
-            * Note: The order of events is important here.
-            * The playback stream must be closed before the recording stream. If the
-            * recording stream were to be closed first the playback stream's
-            * callback may attempt to read from the recording stream
-            * which would cause the app to crash since the recording stream would be
-            * null.
-            */
-            closeStream(mPlayStream);
-            closeStream(mRecordingStream);
+            closeStreams();
             mIsEffectOn = isOn;
        }
     }
     return success;
 }
 
+void LiveEffectEngine::closeStreams() {
+    /*
+    * Note: The order of events is important here.
+    * The playback stream must be closed before the recording stream. If the
+    * recording stream were to be closed first the playback stream's
+    * callback may attempt to read from the recording stream
+    * which would cause the app to crash since the recording stream would be
+    * null.
+    */
+    closeStream(mPlayStream);
+    mFullDuplexPass.setOutputStream(nullptr);
+
+    closeStream(mRecordingStream);
+    mFullDuplexPass.setInputStream(nullptr);
+}
+
 oboe::Result  LiveEffectEngine::openStreams() {
     // Note: The order of stream creation is important. We create the playback
     // stream first, then use properties from the playback stream
@@ -89,11 +89,12 @@
         mSampleRate = oboe::kUnspecified;
         return result;
     } else {
+        // The input stream needs to run at the same sample rate as the output.
         mSampleRate = mPlayStream->getSampleRate();
     }
     warnIfNotLowLatency(mPlayStream);
 
-    setupRecordingStreamParameters(&inBuilder);
+    setupRecordingStreamParameters(&inBuilder, mSampleRate);
     result = inBuilder.openStream(mRecordingStream);
     if (result != oboe::Result::OK) {
         closeStream(mPlayStream);
@@ -101,8 +102,8 @@
     }
     warnIfNotLowLatency(mRecordingStream);
 
-    mFullDuplexPass.setInputStream(mRecordingStream.get());
-    mFullDuplexPass.setOutputStream(mPlayStream.get());
+    mFullDuplexPass.setInputStream(mRecordingStream);
+    mFullDuplexPass.setOutputStream(mPlayStream);
     return result;
 }
 
@@ -112,14 +113,14 @@
  * playback stream.
  *
  * @param builder The recording stream builder
+ * @param sampleRate The desired sample rate of the recording stream
  */
 oboe::AudioStreamBuilder *LiveEffectEngine::setupRecordingStreamParameters(
-    oboe::AudioStreamBuilder *builder) {
-    // This sample uses blocking read() by setting callback to null
-    builder->setCallback(nullptr)
-        ->setDeviceId(mRecordingDeviceId)
+    oboe::AudioStreamBuilder *builder, int32_t sampleRate) {
+    // This sample uses blocking read() because we don't specify a callback
+    builder->setDeviceId(mRecordingDeviceId)
         ->setDirection(oboe::Direction::Input)
-        ->setSampleRate(mSampleRate)
+        ->setSampleRate(sampleRate)
         ->setChannelCount(mInputChannelCount);
     return setupCommonStreamParameters(builder);
 }
@@ -132,7 +133,8 @@
  */
 oboe::AudioStreamBuilder *LiveEffectEngine::setupPlaybackStreamParameters(
     oboe::AudioStreamBuilder *builder) {
-    builder->setCallback(this)
+    builder->setDataCallback(this)
+        ->setErrorCallback(this)
         ->setDeviceId(mPlaybackDeviceId)
         ->setDirection(oboe::Direction::Output)
         ->setChannelCount(mOutputChannelCount);
@@ -158,7 +160,6 @@
     return builder;
 }
 
-
 /**
  * Close the stream. AudioStream::close() is a blocking call so
  * the application does not need to add synchronization between
@@ -182,7 +183,6 @@
     }
 }
 
-
 /**
  * Warn in logcat if non-low latency stream is created
  * @param stream: newly created stream
diff --git a/samples/LiveEffect/src/main/cpp/LiveEffectEngine.h b/samples/LiveEffect/src/main/cpp/LiveEffectEngine.h
index 47a7fca..c12cbdb 100644
--- a/samples/LiveEffect/src/main/cpp/LiveEffectEngine.h
+++ b/samples/LiveEffect/src/main/cpp/LiveEffectEngine.h
@@ -24,11 +24,12 @@
 #include "FullDuplexPass.h"
 
 class LiveEffectEngine : public oboe::AudioStreamCallback {
-   public:
+public:
     LiveEffectEngine();
-    ~LiveEffectEngine();
+
     void setRecordingDeviceId(int32_t deviceId);
     void setPlaybackDeviceId(int32_t deviceId);
+
     /**
      * @param isOn
      * @return true if it succeeds
@@ -36,38 +37,44 @@
     bool setEffectOn(bool isOn);
 
     /*
-     * oboe::AudioStreamCallback interface implementation
+     * oboe::AudioStreamDataCallback interface implementation
      */
     oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream,
                                           void *audioData, int32_t numFrames) override;
+
+    /*
+     * oboe::AudioStreamErrorCallback interface implementation
+     */
     void onErrorBeforeClose(oboe::AudioStream *oboeStream, oboe::Result error) override;
     void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result error) override;
 
     bool setAudioApi(oboe::AudioApi);
     bool isAAudioSupported(void);
 
-   private:
-    FullDuplexPass mFullDuplexPass;
-    bool mIsEffectOn = false;
-    int32_t mRecordingDeviceId = oboe::kUnspecified;
-    int32_t mPlaybackDeviceId = oboe::kUnspecified;
-    oboe::AudioFormat mFormat = oboe::AudioFormat::I16;
-    int32_t mSampleRate = oboe::kUnspecified;
-    int32_t mInputChannelCount = oboe::ChannelCount::Stereo;
-    int32_t mOutputChannelCount = oboe::ChannelCount::Stereo;
+private:
+    FullDuplexPass    mFullDuplexPass;
+    bool              mIsEffectOn = false;
+    int32_t           mRecordingDeviceId = oboe::kUnspecified;
+    int32_t           mPlaybackDeviceId = oboe::kUnspecified;
+    const oboe::AudioFormat mFormat = oboe::AudioFormat::Float; // for easier processing
+    oboe::AudioApi    mAudioApi = oboe::AudioApi::AAudio;
+    int32_t           mSampleRate = oboe::kUnspecified;
+    const int32_t     mInputChannelCount = oboe::ChannelCount::Stereo;
+    const int32_t     mOutputChannelCount = oboe::ChannelCount::Stereo;
 
     std::shared_ptr<oboe::AudioStream> mRecordingStream;
     std::shared_ptr<oboe::AudioStream> mPlayStream;
 
-    oboe::AudioApi mAudioApi = oboe::AudioApi::AAudio;
-
     oboe::Result openStreams();
+
+    void closeStreams();
+
     void closeStream(std::shared_ptr<oboe::AudioStream> &stream);
 
     oboe::AudioStreamBuilder *setupCommonStreamParameters(
         oboe::AudioStreamBuilder *builder);
     oboe::AudioStreamBuilder *setupRecordingStreamParameters(
-        oboe::AudioStreamBuilder *builder);
+        oboe::AudioStreamBuilder *builder, int32_t sampleRate);
     oboe::AudioStreamBuilder *setupPlaybackStreamParameters(
         oboe::AudioStreamBuilder *builder);
     void warnIfNotLowLatency(std::shared_ptr<oboe::AudioStream> &stream);
diff --git a/samples/LiveEffect/src/main/cpp/jni_bridge.cpp b/samples/LiveEffect/src/main/cpp/jni_bridge.cpp
index aa0abd0..eb70e6d 100644
--- a/samples/LiveEffect/src/main/cpp/jni_bridge.cpp
+++ b/samples/LiveEffect/src/main/cpp/jni_bridge.cpp
@@ -38,8 +38,11 @@
 JNIEXPORT void JNICALL
 Java_com_google_oboe_samples_liveEffect_LiveEffectEngine_delete(JNIEnv *env,
                                                                jclass) {
-    delete engine;
-    engine = nullptr;
+    if (engine) {
+        engine->setEffectOn(false);
+        delete engine;
+        engine = nullptr;
+    }
 }
 
 JNIEXPORT jboolean JNICALL
diff --git a/samples/MegaDrone/src/main/cpp/MegaDroneEngine.cpp b/samples/MegaDrone/src/main/cpp/MegaDroneEngine.cpp
index 5bf94ff..ee4de17 100644
--- a/samples/MegaDrone/src/main/cpp/MegaDroneEngine.cpp
+++ b/samples/MegaDrone/src/main/cpp/MegaDroneEngine.cpp
@@ -56,20 +56,24 @@
     return builder.setSharingMode(oboe::SharingMode::Exclusive)
             ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
             ->setFormat(oboe::AudioFormat::Float)
-            ->setCallback(mCallback.get())
+            ->setDataCallback(mDataCallback.get())
+            ->setErrorCallback(mErrorCallback.get())
             ->openStream(mStream);
 }
 
 // Create the callback and set its thread affinity to the supplied CPU core IDs
 void MegaDroneEngine::createCallback(std::vector<int> cpuIds){
-    // Create the callback, we supply ourselves as the parent so that we can restart the stream
+
+    mDataCallback = std::make_unique<DefaultDataCallback>();
+
+    // Create the error callback, we supply ourselves as the parent so that we can restart the stream
     // when it's disconnected
-    mCallback = std::make_unique<DefaultAudioStreamCallback>(*this);
+    mErrorCallback = std::make_unique<DefaultErrorCallback>(*this);
 
     // Bind the audio callback to specific CPU cores as this can help avoid underruns caused by
     // core migrations
-    mCallback->setCpuIds(cpuIds);
-    mCallback->setThreadAffinityEnabled(true);
+    mDataCallback->setCpuIds(cpuIds);
+    mDataCallback->setThreadAffinityEnabled(true);
 }
 
 bool MegaDroneEngine::start(){
@@ -77,7 +81,8 @@
     if (result == Result::OK){
         // Create our synthesizer audio source using the properties of the stream
         mAudioSource = std::make_shared<Synth>(mStream->getSampleRate(), mStream->getChannelCount());
-        mCallback->setSource(std::dynamic_pointer_cast<IRenderableAudio>(mAudioSource));
+        mDataCallback->reset();
+        mDataCallback->setSource(std::dynamic_pointer_cast<IRenderableAudio>(mAudioSource));
         mStream->start();
         return true;
     } else {
diff --git a/samples/MegaDrone/src/main/cpp/MegaDroneEngine.h b/samples/MegaDrone/src/main/cpp/MegaDroneEngine.h
index 9f387bb..d0b84a4 100644
--- a/samples/MegaDrone/src/main/cpp/MegaDroneEngine.h
+++ b/samples/MegaDrone/src/main/cpp/MegaDroneEngine.h
@@ -22,9 +22,10 @@
 #include <vector>
 
 #include "Synth.h"
-#include <DefaultAudioStreamCallback.h>
+#include <DefaultDataCallback.h>
 #include <TappableAudioSource.h>
 #include <IRestartable.h>
+#include <DefaultErrorCallback.h>
 
 using namespace oboe;
 
@@ -46,7 +47,8 @@
 private:
     std::shared_ptr<AudioStream> mStream;
     std::shared_ptr<TappableAudioSource> mAudioSource;
-    std::unique_ptr<DefaultAudioStreamCallback> mCallback;
+    std::unique_ptr<DefaultDataCallback> mDataCallback;
+    std::unique_ptr<DefaultErrorCallback> mErrorCallback;
 
     oboe::Result createPlaybackStream();
     void createCallback(std::vector<int> cpuIds);
diff --git a/samples/RhythmGame/src/main/cpp/Game.cpp b/samples/RhythmGame/src/main/cpp/Game.cpp
index c1ef080..1f50df4 100644
--- a/samples/RhythmGame/src/main/cpp/Game.cpp
+++ b/samples/RhythmGame/src/main/cpp/Game.cpp
@@ -175,7 +175,8 @@
 
     // Create an audio stream
     AudioStreamBuilder builder;
-    builder.setCallback(this);
+    builder.setDataCallback(this);
+    builder.setErrorCallback(this);
     builder.setPerformanceMode(PerformanceMode::LowLatency);
     builder.setSharingMode(SharingMode::Exclusive);
 
diff --git a/samples/RhythmGame/src/main/cpp/Game.h b/samples/RhythmGame/src/main/cpp/Game.h
index 60cce80..cfe1c15 100644
--- a/samples/RhythmGame/src/main/cpp/Game.h
+++ b/samples/RhythmGame/src/main/cpp/Game.h
@@ -51,9 +51,11 @@
     void tick();
     void tap(int64_t eventTimeAsUptime);
 
-    // Inherited from oboe::AudioStreamCallback
+    // Inherited from oboe::AudioStreamDataCallback
     DataCallbackResult
     onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override;
+
+    // Inherited from oboe::AudioStreamErrorCallback
     void onErrorAfterClose(AudioStream *oboeStream, Result error) override;
 
 private:
diff --git a/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp b/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp
index a3f2c5e..1fa06ea 100644
--- a/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp
+++ b/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp
@@ -35,8 +35,8 @@
  *
  */
 HelloOboeEngine::HelloOboeEngine()
-        : mLatencyCallback(std::make_unique<LatencyTuningCallback>(*this)) {
-    start();
+        : mLatencyCallback(std::make_unique<LatencyTuningCallback>()),
+        mErrorCallback(std::make_unique<DefaultErrorCallback>(*this)) {
 }
 
 double HelloOboeEngine::getCurrentOutputLatencyMillis() {
@@ -75,7 +75,6 @@
     std::lock_guard<std::mutex> lock(mLock);
     if (!mStream) return;
 
-    mIsLatencyDetectionSupported = false;
     mLatencyCallback->setBufferTuneEnabled(numBursts == kBufferSizeAutomatic);
     auto result = mStream->setBufferSizeInFrames(
             numBursts * mStream->getFramesPerBurst());
@@ -87,19 +86,16 @@
 }
 
 void HelloOboeEngine::setAudioApi(oboe::AudioApi audioApi) {
-    mIsLatencyDetectionSupported = false;
     mAudioApi = audioApi;
     reopenStream();
 }
 
 void HelloOboeEngine::setChannelCount(int channelCount) {
-    mIsLatencyDetectionSupported = false;
     mChannelCount = channelCount;
     reopenStream();
 }
 
 void HelloOboeEngine::setDeviceId(int32_t deviceId) {
-    mIsLatencyDetectionSupported = false;
     mDeviceId = deviceId;
     if (reopenStream() != oboe::Result::OK) {
         LOGW("Open stream failed, forcing deviceId to Unspecified");
@@ -120,7 +116,8 @@
     return builder.setSharingMode(oboe::SharingMode::Exclusive)
         ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
         ->setFormat(oboe::AudioFormat::Float)
-        ->setCallback(mLatencyCallback.get())
+        ->setDataCallback(mLatencyCallback.get())
+        ->setErrorCallback(mErrorCallback.get())
         ->setAudioApi(mAudioApi)
         ->setChannelCount(mChannelCount)
         ->setDeviceId(mDeviceId)
@@ -129,6 +126,7 @@
 
 void HelloOboeEngine::restart() {
     // The stream will have already been closed by the error callback.
+    mLatencyCallback->reset();
     start();
 }
 
@@ -150,18 +148,22 @@
                 mStream->getDeviceId());
     } else {
         LOGE("Error creating playback stream. Error: %s", oboe::convertToText(result));
+        mIsLatencyDetectionSupported = false;
     }
     return result;
 }
 
-oboe::Result HelloOboeEngine::reopenStream() {
-    {
-        // Stop and close in case not already closed.
-        std::lock_guard<std::mutex> lock(mLock);
-        if (mStream) {
-            mStream->stop();
-            mStream->close();
-        }
+void HelloOboeEngine::stop() {
+    // Stop, close and delete in case not already closed.
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mStream) {
+        mStream->stop();
+        mStream->close();
+        mStream.reset();
     }
+}
+
+oboe::Result HelloOboeEngine::reopenStream() {
+    stop();
     return start();
 }
diff --git a/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h b/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h
index 1c43282..29231ee 100644
--- a/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h
+++ b/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h
@@ -22,6 +22,7 @@
 #include "SoundGenerator.h"
 #include "LatencyTuningCallback.h"
 #include "IRestartable.h"
+#include "DefaultErrorCallback.h"
 
 constexpr int32_t kBufferSizeAutomatic = 0;
 
@@ -34,6 +35,17 @@
 
     void tap(bool isDown);
 
+    /**
+     * Open and start a stream.
+     * @return error or OK
+     */
+    oboe::Result start();
+
+    /**
+     * Stop and close the stream.
+     */
+    void stop();
+
     // From IRestartable
     void restart() override;
 
@@ -77,11 +89,10 @@
 private:
     oboe::Result reopenStream();
     oboe::Result createPlaybackStream();
-    void         updateLatencyDetection();
-    oboe::Result start();
 
     std::shared_ptr<oboe::AudioStream> mStream;
     std::unique_ptr<LatencyTuningCallback> mLatencyCallback;
+    std::unique_ptr<DefaultErrorCallback> mErrorCallback;
     std::shared_ptr<SoundGenerator> mAudioSource;
     bool mIsLatencyDetectionSupported = false;
 
diff --git a/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp b/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp
index eb6c9a8..7d53c43 100644
--- a/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp
+++ b/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp
@@ -37,7 +37,7 @@
     */
     if (Trace::isEnabled()) Trace::beginSection("numFrames %d, Underruns %d, buffer size %d",
         numFrames, underrunCountResult.value(), bufferSize);
-    auto result = DefaultAudioStreamCallback::onAudioReady(oboeStream, audioData, numFrames);
+    auto result = DefaultDataCallback::onAudioReady(oboeStream, audioData, numFrames);
     if (Trace::isEnabled()) Trace::endSection();
     return result;
 }
diff --git a/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h b/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h
index 3b61a16..1605154 100644
--- a/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h
+++ b/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h
@@ -22,19 +22,19 @@
 #include <oboe/LatencyTuner.h>
 
 #include <TappableAudioSource.h>
-#include <DefaultAudioStreamCallback.h>
+#include <DefaultDataCallback.h>
 #include <trace.h>
 
 /**
- * This callback object extends the functionality of `DefaultAudioStreamCallback` by automatically
+ * This callback object extends the functionality of `DefaultDataCallback` by automatically
  * tuning the latency of the audio stream. @see onAudioReady for more details on this.
  *
  * It also demonstrates how to use tracing functions for logging inside the audio callback without
  * blocking.
  */
-class LatencyTuningCallback: public DefaultAudioStreamCallback {
+class LatencyTuningCallback: public DefaultDataCallback {
 public:
-    LatencyTuningCallback(IRestartable &mParent) : DefaultAudioStreamCallback(mParent) {
+    LatencyTuningCallback() : DefaultDataCallback() {
 
         // Initialize the trace functions, this enables you to output trace statements without
         // blocking. See https://developer.android.com/studio/profile/systrace-commandline.html
diff --git a/samples/hello-oboe/src/main/cpp/jni_bridge.cpp b/samples/hello-oboe/src/main/cpp/jni_bridge.cpp
index a8e90b6..0efaff0 100644
--- a/samples/hello-oboe/src/main/cpp/jni_bridge.cpp
+++ b/samples/hello-oboe/src/main/cpp/jni_bridge.cpp
@@ -32,6 +32,17 @@
         jclass /*unused*/) {
     // We use std::nothrow so `new` returns a nullptr if the engine creation fails
     HelloOboeEngine *engine = new(std::nothrow) HelloOboeEngine();
+    if (engine == nullptr) {
+        LOGE("Could not instantiate HelloOboeEngine");
+        return 0;
+    }
+    auto result = engine->start();
+    if (result != oboe::Result::OK) {
+        LOGE("Opening and starting stream failed. Returned %d", result);
+        engine->stop();
+        delete engine;
+        return 0;
+    }
     return reinterpret_cast<jlong>(engine);
 }
 
@@ -41,7 +52,9 @@
         jclass,
         jlong engineHandle) {
 
-    delete reinterpret_cast<HelloOboeEngine *>(engineHandle);
+    HelloOboeEngine *engine = reinterpret_cast<HelloOboeEngine *>(engineHandle);
+    engine->stop();
+    delete engine;
 }
 
 JNIEXPORT void JNICALL
@@ -151,10 +164,11 @@
 }
 
 JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_hellooboe_PlaybackEngine_native_1setDefaultStreamValues(JNIEnv *env,
-                                                                                  jclass type,
-                                                                                  jint sampleRate,
-                                                                                  jint framesPerBurst) {
+Java_com_google_oboe_samples_hellooboe_PlaybackEngine_native_1setDefaultStreamValues(
+        JNIEnv *env,
+        jclass type,
+        jint sampleRate,
+        jint framesPerBurst) {
     oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;
     oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
 }
diff --git a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
index 44703da..f873d56 100644
--- a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
+++ b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
@@ -64,8 +64,9 @@
     __android_log_print(ANDROID_LOG_INFO, TAG, "==== onErrorAfterClose() error:%d", error);
 
     resetAll();
-    openStream();
-    mOutputReset = true;
+    if (openStream() && startStream()) {
+        mOutputReset = true;
+    }
 }
 
 void SimpleMultiPlayer::onErrorBeforeClose(AudioStream *, Result error) {
diff --git a/samples/shared/DefaultAudioStreamCallback.h b/samples/shared/DefaultDataCallback.h
similarity index 79%
rename from samples/shared/DefaultAudioStreamCallback.h
rename to samples/shared/DefaultDataCallback.h
index 8fd07eb..e7f858e 100644
--- a/samples/shared/DefaultAudioStreamCallback.h
+++ b/samples/shared/DefaultDataCallback.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef SAMPLES_DEFAULT_AUDIO_STREAM_CALLBACK_H
-#define SAMPLES_DEFAULT_AUDIO_STREAM_CALLBACK_H
+#ifndef SAMPLES_DEFAULT_DATA_CALLBACK_H
+#define SAMPLES_DEFAULT_DATA_CALLBACK_H
 
 
 #include <vector>
@@ -26,16 +26,12 @@
 #include "IRestartable.h"
 
 /**
- * This is a callback object which will render data from an `IRenderableAudio` source. It is
- * constructed using an `IRestartable` which allows it to automatically restart the parent object
- * if the stream is disconnected (for example, when headphones are attached).
- *
- * @param IRestartable - the object which should be restarted when the stream is disconnected
+ * This is a callback object which will render data from an `IRenderableAudio` source.
  */
-class DefaultAudioStreamCallback : public oboe::AudioStreamCallback {
+class DefaultDataCallback : public oboe::AudioStreamDataCallback {
 public:
-    DefaultAudioStreamCallback(IRestartable &parent): mParent(parent) {}
-    virtual ~DefaultAudioStreamCallback() = default;
+    DefaultDataCallback() {}
+    virtual ~DefaultDataCallback() = default;
 
     virtual oboe::DataCallbackResult
     onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
@@ -56,21 +52,17 @@
         return oboe::DataCallbackResult::Continue;
     }
 
-    virtual void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result error) override {
-        // Restart the stream when it errors out with disconnect
-        if (error == oboe::Result::ErrorDisconnected) {
-            LOGE("Restarting AudioStream after disconnect");
-            mParent.restart();
-        } else {
-            LOGE("Unknown error");
-        }
-        mIsThreadAffinitySet = false;
-    }
-
     void setSource(std::shared_ptr<IRenderableAudio> renderable) {
         mRenderable = renderable;
     }
 
+    /**
+     * Reset the callback to its initial state.
+     */
+    void reset(){
+        mIsThreadAffinitySet = false;
+    }
+
     std::shared_ptr<IRenderableAudio> getSource() {
         return mRenderable;
     }
@@ -98,7 +90,6 @@
 
 private:
     std::shared_ptr<IRenderableAudio> mRenderable;
-    IRestartable &mParent;
     std::vector<int> mCpuIds; // IDs of CPU cores which the audio callback should be bound to
     std::atomic<bool> mIsThreadAffinityEnabled { false };
     std::atomic<bool> mIsThreadAffinitySet { false };
@@ -139,4 +130,4 @@
 
 };
 
-#endif //SAMPLES_DEFAULT_AUDIO_STREAM_CALLBACK_H
+#endif //SAMPLES_DEFAULT_DATA_CALLBACK_H
diff --git a/samples/shared/DefaultErrorCallback.h b/samples/shared/DefaultErrorCallback.h
new file mode 100644
index 0000000..5bbb892
--- /dev/null
+++ b/samples/shared/DefaultErrorCallback.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SAMPLES_DEFAULT_ERROR_CALLBACK_H
+#define SAMPLES_DEFAULT_ERROR_CALLBACK_H
+
+#include <vector>
+#include <oboe/AudioStreamCallback.h>
+#include <logging_macros.h>
+
+#include "IRestartable.h"
+
+/**
+ * This is a callback object which will be called when a stream error occurs.
+ *
+ * It is constructed using an `IRestartable` which allows it to automatically restart the parent
+ * object if the stream is disconnected (for example, when headphones are attached).
+ *
+ * @param IRestartable - the object which should be restarted when the stream is disconnected
+ */
+class DefaultErrorCallback : public oboe::AudioStreamErrorCallback {
+public:
+
+    DefaultErrorCallback(IRestartable &parent): mParent(parent) {}
+    virtual ~DefaultErrorCallback() = default;
+
+    virtual void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result error) override {
+        // Restart the stream if the error is a disconnect, otherwise do nothing and log the error
+        // reason.
+        if (error == oboe::Result::ErrorDisconnected) {
+            LOGI("Restarting AudioStream");
+            mParent.restart();
+        }
+        LOGE("Error was %s", oboe::convertToText(error));
+    }
+
+private:
+    IRestartable &mParent;
+
+};
+
+
+#endif //SAMPLES_DEFAULT_ERROR_CALLBACK_H
diff --git a/src/aaudio/AudioStreamAAudio.cpp b/src/aaudio/AudioStreamAAudio.cpp
index 6d77c50..cb81762 100644
--- a/src/aaudio/AudioStreamAAudio.cpp
+++ b/src/aaudio/AudioStreamAAudio.cpp
@@ -62,14 +62,16 @@
 static void oboe_aaudio_error_thread_proc(AudioStreamAAudio *oboeStream,
                                           Result error) {
     LOGD("%s() - entering >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", __func__);
-    oboeStream->requestStop();
-    if (oboeStream->getCallback() != nullptr) {
-        oboeStream->getCallback()->onErrorBeforeClose(oboeStream, error);
-    }
-    oboeStream->close();
-    if (oboeStream->getCallback() != nullptr) {
+    AudioStreamErrorCallback *errorCallback = oboeStream->getErrorCallback();
+    if (errorCallback == nullptr) return; // should be impossible
+    bool isErrorHandled = errorCallback->onError(oboeStream, error);
+
+    if (!isErrorHandled) {
+        oboeStream->requestStop();
+        errorCallback->onErrorBeforeClose(oboeStream, error);
+        oboeStream->close();
         // Warning, oboeStream may get deleted by this callback.
-        oboeStream->getCallback()->onErrorAfterClose(oboeStream, error);
+        errorCallback->onErrorAfterClose(oboeStream, error);
     }
     LOGD("%s() - exiting <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", __func__);
 }
@@ -92,7 +94,7 @@
     : AudioStream(builder)
     , mAAudioStream(nullptr) {
     mCallbackThreadEnabled.store(false);
-    isSupported();
+    mLibLoader = AAudioLoader::getInstance();
 }
 
 bool AudioStreamAAudio::isSupported() {
@@ -101,15 +103,28 @@
     return openResult == 0;
 }
 
-// Static 'C' wrapper for the error callback method.
+// Static method for the error callback.
+// We use a method so we can access protected methods on the stream.
 // Launch a thread to handle the error.
 // That other thread can safely stop, close and delete the stream.
 void AudioStreamAAudio::internalErrorCallback(
         AAudioStream *stream,
         void *userData,
         aaudio_result_t error) {
+    oboe::Result oboeResult = static_cast<Result>(error);
     AudioStreamAAudio *oboeStream = reinterpret_cast<AudioStreamAAudio*>(userData);
 
+    // Coerce the error code if needed to workaround a regression in RQ1A that caused
+    // the wrong code to be passed when headsets plugged in. See b/173928197.
+    if (OboeGlobals::areWorkaroundsEnabled()
+            && getSdkVersion() == __ANDROID_API_R__
+            && oboeResult == oboe::Result::ErrorTimeout) {
+        oboeResult = oboe::Result::ErrorDisconnected;
+        LOGD("%s() ErrorTimeout changed to ErrorDisconnected to fix b/173928197", __func__);
+    }
+
+    oboeStream->mErrorCallbackResult = oboeResult;
+
     // Prevents deletion of the stream if the app is using AudioStreamBuilder::openStream(shared_ptr)
     std::shared_ptr<AudioStream> sharedStream = oboeStream->lockWeakThis();
 
@@ -118,16 +133,14 @@
     if (oboeStream->wasErrorCallbackCalled()) { // block extra error callbacks
         LOGE("%s() multiple error callbacks called!", __func__);
     } else if (stream != oboeStream->getUnderlyingStream()) {
-        LOGW("%s() stream already closed or closing", __func__); // can happen if there are bugs
+        LOGW("%s() stream already closed or closing", __func__); // might happen if there are bugs
     } else if (sharedStream) {
         // Handle error on a separate thread using shared pointer.
-        std::thread t(oboe_aaudio_error_thread_proc_shared, sharedStream,
-                      static_cast<Result>(error));
+        std::thread t(oboe_aaudio_error_thread_proc_shared, sharedStream, oboeResult);
         t.detach();
     } else {
         // Handle error on a separate thread.
-        std::thread t(oboe_aaudio_error_thread_proc, oboeStream,
-                      static_cast<Result>(error));
+        std::thread t(oboe_aaudio_error_thread_proc, oboeStream, oboeResult);
         t.detach();
     }
 }
@@ -229,13 +242,19 @@
 
     // TODO get more parameters from the builder?
 
-    if (mStreamCallback != nullptr) {
+    if (isDataCallbackSpecified()) {
         mLibLoader->builder_setDataCallback(aaudioBuilder, oboe_aaudio_data_callback_proc, this);
-        mLibLoader->builder_setFramesPerDataCallback(aaudioBuilder, getFramesPerCallback());
-        // If the data callback is not being used then the write method will return an error
-        // and the app can stop and close the stream.
+        mLibLoader->builder_setFramesPerDataCallback(aaudioBuilder, getFramesPerDataCallback());
+
+        if (!isErrorCallbackSpecified()) {
+            // The app did not specify a callback so we should specify
+            // our own so the stream gets closed and stopped.
+            mErrorCallback = &mDefaultErrorCallback;
+        }
         mLibLoader->builder_setErrorCallback(aaudioBuilder, internalErrorCallback, this);
     }
+    // Else if the data callback is not being used then the write method will return an error
+    // and the app can stop and close the stream.
 
     // ============= OPEN THE STREAM ================
     {
@@ -357,7 +376,7 @@
                 return Result::OK;
             }
         }
-        if (mStreamCallback != nullptr) { // Was a callback requested?
+        if (isDataCallbackSpecified()) {
             setDataCallbackEnabled(true);
         }
         return static_cast<Result>(mLibLoader->stream_requestStart(stream));
diff --git a/src/aaudio/AudioStreamAAudio.h b/src/aaudio/AudioStreamAAudio.h
index 9095817..83f4b2f 100644
--- a/src/aaudio/AudioStreamAAudio.h
+++ b/src/aaudio/AudioStreamAAudio.h
@@ -118,10 +118,13 @@
 
     std::atomic<bool>    mCallbackThreadEnabled;
 
-    // pointer to the underlying AAudio stream, valid if open, null if closed
+    // pointer to the underlying 'C' AAudio stream, valid if open, null if closed
     std::atomic<AAudioStream *> mAAudioStream{nullptr};
 
     static AAudioLoader *mLibLoader;
+
+    // We may not use this but it is so small that it is not worth allocating dynamically.
+    AudioStreamErrorCallback mDefaultErrorCallback;
 };
 
 } // namespace oboe
diff --git a/src/common/AudioSourceCaller.cpp b/src/common/AudioSourceCaller.cpp
index 0180c22..a19cf81 100644
--- a/src/common/AudioSourceCaller.cpp
+++ b/src/common/AudioSourceCaller.cpp
@@ -20,7 +20,7 @@
 using namespace flowgraph;
 
 int32_t AudioSourceCaller::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) {
-    oboe::AudioStreamCallback *callback = mStream->getCallback();
+    AudioStreamDataCallback *callback = mStream->getDataCallback();
     int32_t result = 0;
     int32_t numFrames = numBytes / mStream->getBytesPerFrame();
     if (callback != nullptr) {
diff --git a/src/common/AudioStream.cpp b/src/common/AudioStream.cpp
index 7bcd087..8a9cd45 100644
--- a/src/common/AudioStream.cpp
+++ b/src/common/AudioStream.cpp
@@ -59,10 +59,10 @@
     }
 
     DataCallbackResult result;
-    if (mStreamCallback == nullptr) {
-        result = onDefaultCallback(audioData, numFrames);
+    if (mDataCallback) {
+        result = mDataCallback->onAudioReady(this, audioData, numFrames);
     } else {
-        result = mStreamCallback->onAudioReady(this, audioData, numFrames);
+        result = onDefaultCallback(audioData, numFrames);
     }
     // On Oreo, we might get called after returning stop.
     // So block that here.
diff --git a/src/common/AudioStreamBuilder.cpp b/src/common/AudioStreamBuilder.cpp
index 910b154..dffcd75 100644
--- a/src/common/AudioStreamBuilder.cpp
+++ b/src/common/AudioStreamBuilder.cpp
@@ -82,7 +82,7 @@
 bool AudioStreamBuilder::isCompatible(AudioStreamBase &other) {
     return (getSampleRate() == oboe::Unspecified || getSampleRate() == other.getSampleRate())
            && (getFormat() == (AudioFormat)oboe::Unspecified || getFormat() == other.getFormat())
-           && (getFramesPerCallback() == oboe::Unspecified || getFramesPerCallback() == other.getFramesPerCallback())
+           && (getFramesPerDataCallback() == oboe::Unspecified || getFramesPerDataCallback() == other.getFramesPerDataCallback())
            && (getChannelCount() == oboe::Unspecified || getChannelCount() == other.getChannelCount());
 }
 
@@ -131,8 +131,8 @@
             if (getSampleRate() == oboe::Unspecified) {
                 parentBuilder.setSampleRate(tempStream->getSampleRate());
             }
-            if (getFramesPerCallback() == oboe::Unspecified) {
-                parentBuilder.setFramesPerCallback(tempStream->getFramesPerCallback());
+            if (getFramesPerDataCallback() == oboe::Unspecified) {
+                parentBuilder.setFramesPerCallback(tempStream->getFramesPerDataCallback());
             }
 
             // Use childStream in a FilterAudioStream.
diff --git a/src/common/DataConversionFlowGraph.cpp b/src/common/DataConversionFlowGraph.cpp
index 7cc742e..2829e6f 100644
--- a/src/common/DataConversionFlowGraph.cpp
+++ b/src/common/DataConversionFlowGraph.cpp
@@ -82,12 +82,12 @@
     AudioFormat sourceFormat = sourceStream->getFormat();
     int32_t sourceChannelCount = sourceStream->getChannelCount();
     int32_t sourceSampleRate = sourceStream->getSampleRate();
-    int32_t sourceFramesPerCallback = sourceStream->getFramesPerCallback();
+    int32_t sourceFramesPerCallback = sourceStream->getFramesPerDataCallback();
 
     AudioFormat sinkFormat = sinkStream->getFormat();
     int32_t sinkChannelCount = sinkStream->getChannelCount();
     int32_t sinkSampleRate = sinkStream->getSampleRate();
-    int32_t sinkFramesPerCallback = sinkStream->getFramesPerCallback();
+    int32_t sinkFramesPerCallback = sinkStream->getFramesPerDataCallback();
 
     LOGI("%s() flowgraph converts channels: %d to %d, format: %d to %d"
          ", rate: %d to %d, cbsize: %d to %d, qual = %d",
@@ -101,8 +101,9 @@
     // Source
     // IF OUTPUT and using a callback then call back to the app using a SourceCaller.
     // OR IF INPUT and NOT using a callback then read from the child stream using a SourceCaller.
-    if ((sourceStream->getCallback() != nullptr && isOutput)
-        || (sourceStream->getCallback() == nullptr && isInput)) {
+    bool isDataCallbackSpecified = sourceStream->isDataCallbackSpecified();
+    if ((isDataCallbackSpecified && isOutput)
+        || (!isDataCallbackSpecified && isInput)) {
         int32_t actualSourceFramesPerCallback = (sourceFramesPerCallback == kUnspecified)
                 ? sourceStream->getFramesPerBurst()
                 : sourceFramesPerCallback;
@@ -236,7 +237,7 @@
 
 int32_t DataConversionFlowGraph::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) {
     int32_t numFrames = numBytes / mFilterStream->getBytesPerFrame();
-    mCallbackResult = mFilterStream->getCallback()->onAudioReady(mFilterStream, buffer, numFrames);
+    mCallbackResult = mFilterStream->getDataCallback()->onAudioReady(mFilterStream, buffer, numFrames);
     // TODO handle STOP from callback, process data remaining in the block adapter
     return numBytes;
-}
\ No newline at end of file
+}
diff --git a/src/common/FilterAudioStream.cpp b/src/common/FilterAudioStream.cpp
index a471583..975b03d 100644
--- a/src/common/FilterAudioStream.cpp
+++ b/src/common/FilterAudioStream.cpp
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "OboeDebug.h"
 #include "FilterAudioStream.h"
 
 using namespace oboe;
@@ -90,3 +91,16 @@
     return ResultWithValue<int32_t>::createBasedOnSign(framesRead);
 }
 
+DataCallbackResult FilterAudioStream::onAudioReady(AudioStream *oboeStream,
+                                void *audioData,
+                                int32_t numFrames) {
+    int32_t framesProcessed;
+    if (oboeStream->getDirection() == Direction::Output) {
+        framesProcessed = mFlowGraph->read(audioData, numFrames, 0 /* timeout */);
+    } else {
+        framesProcessed = mFlowGraph->write(audioData, numFrames);
+    }
+    return (framesProcessed < numFrames)
+           ? DataCallbackResult::Stop
+           : mFlowGraph->getDataCallbackResult();
+}
diff --git a/src/common/FilterAudioStream.h b/src/common/FilterAudioStream.h
index 3949de7..210e9d1 100644
--- a/src/common/FilterAudioStream.h
+++ b/src/common/FilterAudioStream.h
@@ -42,8 +42,11 @@
     : AudioStream(builder)
     , mChildStream(childStream) {
         // Intercept the callback if used.
-        if (builder.getCallback() != nullptr) {
-            mStreamCallback = mChildStream->swapCallback(this);
+        if (builder.isErrorCallbackSpecified()) {
+            mErrorCallback = mChildStream->swapErrorCallback(this);
+        }
+        if (builder.isDataCallbackSpecified()) {
+            mDataCallback = mChildStream->swapDataCallback(this);
         } else {
             const int size = childStream->getFramesPerBurst() * childStream->getBytesPerFrame();
             mBlockingBuffer = std::make_unique<uint8_t[]>(size);
@@ -52,6 +55,7 @@
         // Copy parameters that may not match builder.
         mBufferCapacityInFrames = mChildStream->getBufferCapacityInFrames();
         mPerformanceMode = mChildStream->getPerformanceMode();
+        mInputPreset = mChildStream->getInputPreset();
     }
 
     virtual ~FilterAudioStream() = default;
@@ -175,32 +179,36 @@
 
     DataCallbackResult onAudioReady(AudioStream *oboeStream,
             void *audioData,
-            int32_t numFrames) override {
-        int32_t framesProcessed;
-        if (oboeStream->getDirection() == Direction::Output) {
-            framesProcessed = mFlowGraph->read(audioData, numFrames, 0 /* timeout */);
-        } else {
-            framesProcessed = mFlowGraph->write(audioData, numFrames);
+            int32_t numFrames) override;
+
+    bool onError(AudioStream * audioStream, Result error) override {
+        if (mErrorCallback != nullptr) {
+            return mErrorCallback->onError(this, error);
         }
-        return (framesProcessed < numFrames)
-                ? DataCallbackResult::Stop
-                : mFlowGraph->getDataCallbackResult();
+        return false;
     }
 
     void onErrorBeforeClose(AudioStream *oboeStream, Result error) override {
-        if (mStreamCallback != nullptr) {
-            mStreamCallback->onErrorBeforeClose(this, error);
+        if (mErrorCallback != nullptr) {
+            mErrorCallback->onErrorBeforeClose(this, error);
         }
     }
 
     void onErrorAfterClose(AudioStream *oboeStream, Result error) override {
         // Close this parent stream because the callback will only close the child.
         AudioStream::close();
-        if (mStreamCallback != nullptr) {
-            mStreamCallback->onErrorAfterClose(this, error);
+        if (mErrorCallback != nullptr) {
+            mErrorCallback->onErrorAfterClose(this, error);
         }
     }
 
+    /**
+     * @return last result passed from an error callback
+     */
+    oboe::Result getLastErrorCallbackResult() const override {
+        return mChildStream->getLastErrorCallbackResult();
+    }
+
 private:
 
     std::unique_ptr<AudioStream>             mChildStream; // this stream wraps the child stream
diff --git a/src/common/LatencyTuner.cpp b/src/common/LatencyTuner.cpp
index 5a0d037..0ac2975 100644
--- a/src/common/LatencyTuner.cpp
+++ b/src/common/LatencyTuner.cpp
@@ -64,6 +64,9 @@
                 // or was from stream->getBufferCapacityInFrames())
                 if (requestedBufferSize > mMaxBufferSize) requestedBufferSize = mMaxBufferSize;
 
+                // Note that this will not allocate more memory. It simply determines
+                // how much of the existing buffer capacity will be used. The size will be
+                // clipped to the bufferCapacity by AAudio.
                 auto setBufferResult = mStream.setBufferSizeInFrames(requestedBufferSize);
                 if (setBufferResult != Result::OK) {
                     result = setBufferResult;
diff --git a/src/common/QuirksManager.cpp b/src/common/QuirksManager.cpp
index 21a5204..aa285de 100644
--- a/src/common/QuirksManager.cpp
+++ b/src/common/QuirksManager.cpp
@@ -138,8 +138,8 @@
     // know if we will get an MMAP stream. So, to be safe, just do the conversion in Oboe.
     if (OboeGlobals::areWorkaroundsEnabled()
             && builder.willUseAAudio()
-            && builder.getCallback() != nullptr
-            && builder.getFramesPerCallback() != 0
+            && builder.isDataCallbackSpecified()
+            && builder.getFramesPerDataCallback() != 0
             && getSdkVersion() <= __ANDROID_API_R__) {
         LOGI("QuirksManager::%s() avoid setFramesPerCallback(n>0)", __func__);
         childBuilder.setFramesPerCallback(oboe::Unspecified);
diff --git a/src/common/Utilities.cpp b/src/common/Utilities.cpp
index c3acf47..d38874b 100644
--- a/src/common/Utilities.cpp
+++ b/src/common/Utilities.cpp
@@ -183,7 +183,7 @@
      <<"BufferCapacity: "<<stream->getBufferCapacityInFrames()<<std::endl
      <<"BufferSize: "<<stream->getBufferSizeInFrames()<<std::endl
      <<"FramesPerBurst: "<< stream->getFramesPerBurst()<<std::endl
-     <<"FramesPerCallback: "<<stream->getFramesPerCallback()<<std::endl
+     <<"FramesPerDataCallback: "<<stream->getFramesPerDataCallback()<<std::endl
      <<"SampleRate: "<<stream->getSampleRate()<<std::endl
      <<"ChannelCount: "<<stream->getChannelCount()<<std::endl
      <<"Format: "<<oboe::convertToText(stream->getFormat())<<std::endl
diff --git a/src/flowgraph/resampler/PolyphaseResampler.h b/src/flowgraph/resampler/PolyphaseResampler.h
index c7de118..52671cd 100644
--- a/src/flowgraph/resampler/PolyphaseResampler.h
+++ b/src/flowgraph/resampler/PolyphaseResampler.h
@@ -25,8 +25,8 @@
 
 namespace resampler {
 /**
- * Resample that is optimized for a reduced ratio of sample rates.
- * All of the coefficients for eacxh possible phase value are precalculated.
+ * Resampler that is optimized for a reduced ratio of sample rates.
+ * All of the coefficients for each possible phase value are pre-calculated.
  */
 class PolyphaseResampler : public MultiChannelResampler {
 public:
diff --git a/src/flowgraph/resampler/README.md b/src/flowgraph/resampler/README.md
index ecf030f..5ea97dc 100644
--- a/src/flowgraph/resampler/README.md
+++ b/src/flowgraph/resampler/README.md
@@ -29,11 +29,11 @@
 
 Note that the number of output frames generated for a given number of input frames can vary.
 
-For example, suppose you are converting from 44100 Hz to 48000 Hz and using an input buffer with 940 frames. If you calculate the number of output frames you get:
+For example, suppose you are converting from 44100 Hz to 48000 Hz and using an input buffer with 960 frames. If you calculate the number of output frames you get:
 
-    940 * 48000 * 44100 = 1023.1292517...
+    960 * 48000 * 44100 = 1044.897959...
     
-You cannot generate a fractional number of frames. So the resampler will sometimes generate 1023 frames and sometimes 1024 frames. On average it will generate 1023.1292517 frames. The resampler stores the fraction internally and keeps track of when to consume or generate a frame.
+You cannot generate a fractional number of frames. So the resampler will sometimes generate 1044 frames and sometimes 1045 frames. On average it will generate 1044.897959 frames. The resampler stores the fraction internally and keeps track of when to consume or generate a frame.
 
 You can either use a fixed number of input frames or a fixed number of output frames. The other frame count will vary.
 
diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp
index 8526765..b07b0cc 100644
--- a/src/opensles/AudioInputStreamOpenSLES.cpp
+++ b/src/opensles/AudioInputStreamOpenSLES.cpp
@@ -156,14 +156,19 @@
         LOGW("%s() GetInterface(SL_IID_ANDROIDCONFIGURATION) failed with %s",
              __func__, getSLErrStr(result));
     } else {
+        if (getInputPreset() == InputPreset::VoicePerformance) {
+            LOGD("OpenSL ES does not support InputPreset::VoicePerformance. Use VoiceRecognition.");
+            mInputPreset = InputPreset::VoiceRecognition;
+        }
         SLuint32 presetValue = OpenSLES_convertInputPreset(getInputPreset());
         result = (*configItf)->SetConfiguration(configItf,
                                          SL_ANDROID_KEY_RECORDING_PRESET,
                                          &presetValue,
                                          sizeof(SLuint32));
         if (SL_RESULT_SUCCESS != result
-            && presetValue != SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION) {
+                && presetValue != SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION) {
             presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
+            LOGD("Setting InputPreset %d failed. Using VoiceRecognition instead.", getInputPreset());
             mInputPreset = InputPreset::VoiceRecognition;
             (*configItf)->SetConfiguration(configItf,
                                              SL_ANDROID_KEY_RECORDING_PRESET,
@@ -215,19 +220,16 @@
 
 Result AudioInputStreamOpenSLES::close() {
     LOGD("AudioInputStreamOpenSLES::%s()", __func__);
-    mLock.lock();
+    std::lock_guard<std::mutex> lock(mLock);
     Result result = Result::OK;
     if (getState() == StreamState::Closed){
         result = Result::ErrorClosed;
     } else {
-        mLock.unlock(); // avoid recursive lock
-        requestStop();
-        mLock.lock();
+        requestStop_l();
         // invalidate any interfaces
         mRecordInterface = nullptr;
-        result = AudioStreamOpenSLES::close();
+        result = AudioStreamOpenSLES::close_l();
     }
-    mLock.unlock(); // avoid recursive lock
     return result;
 }
 
@@ -295,8 +297,12 @@
 
 Result AudioInputStreamOpenSLES::requestStop() {
     LOGD("AudioInputStreamOpenSLES(): %s() called", __func__);
-
     std::lock_guard<std::mutex> lock(mLock);
+    return requestStop_l();
+}
+
+// Call under mLock
+Result AudioInputStreamOpenSLES::requestStop_l() {
     StreamState initialState = getState();
     switch (initialState) {
         case StreamState::Stopping:
diff --git a/src/opensles/AudioInputStreamOpenSLES.h b/src/opensles/AudioInputStreamOpenSLES.h
index 7be1c96..08e7a05 100644
--- a/src/opensles/AudioInputStreamOpenSLES.h
+++ b/src/opensles/AudioInputStreamOpenSLES.h
@@ -46,6 +46,7 @@
     Result requestStop() override;
 
 protected:
+    Result requestStop_l();
 
     Result updateServiceFrameCounter() override;
 
diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp
index cdb8883..5791b5e 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.cpp
+++ b/src/opensles/AudioOutputStreamOpenSLES.cpp
@@ -243,19 +243,17 @@
 }
 
 Result AudioOutputStreamOpenSLES::close() {
-    mLock.lock();
+    LOGD("AudioOutputStreamOpenSLES::%s()", __func__);
+    std::lock_guard<std::mutex> lock(mLock);
     Result result = Result::OK;
     if (getState() == StreamState::Closed){
         result = Result::ErrorClosed;
     } else {
-        mLock.unlock(); // avoid recursive lock
-        requestPause();
-        mLock.lock();
+        requestPause_l();
         // invalidate any interfaces
         mPlayInterface = nullptr;
-        result = AudioStreamOpenSLES::close();
+        result = AudioStreamOpenSLES::close_l();
     }
-    mLock.unlock(); // avoid recursive lock
     return result;
 }
 
@@ -317,8 +315,12 @@
 
 Result AudioOutputStreamOpenSLES::requestPause() {
     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
-
     std::lock_guard<std::mutex> lock(mLock);
+    return requestPause_l();
+}
+
+// Call under mLock
+Result AudioOutputStreamOpenSLES::requestPause_l() {
     StreamState initialState = getState();
     switch (initialState) {
         case StreamState::Pausing:
@@ -374,8 +376,8 @@
 
 Result AudioOutputStreamOpenSLES::requestStop() {
     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
-
     std::lock_guard<std::mutex> lock(mLock);
+
     StreamState initialState = getState();
     switch (initialState) {
         case StreamState::Stopping:
diff --git a/src/opensles/AudioOutputStreamOpenSLES.h b/src/opensles/AudioOutputStreamOpenSLES.h
index d74faf6..ed11eb9 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.h
+++ b/src/opensles/AudioOutputStreamOpenSLES.h
@@ -45,6 +45,7 @@
     Result requestStop() override;
 
 protected:
+    Result requestPause_l();
 
     void setFramesRead(int64_t framesRead);
 
diff --git a/src/opensles/AudioStreamBuffered.cpp b/src/opensles/AudioStreamBuffered.cpp
index 85b9f8e..298c1eb 100644
--- a/src/opensles/AudioStreamBuffered.cpp
+++ b/src/opensles/AudioStreamBuffered.cpp
@@ -110,12 +110,22 @@
 
 // Common code for read/write.
 // @return Result::OK with frames read/written, or Result::Error*
-ResultWithValue<int32_t> AudioStreamBuffered::transfer(void *buffer,
-                                      int32_t numFrames,
-                                      int64_t timeoutNanoseconds) {
+ResultWithValue<int32_t> AudioStreamBuffered::transfer(
+        void *readBuffer,
+        const void *writeBuffer,
+        int32_t numFrames,
+        int64_t timeoutNanoseconds) {
     // Validate arguments.
-    if (buffer == nullptr) {
-        LOGE("AudioStreamBuffered::%s(): buffer is NULL", __func__);
+    if (readBuffer != nullptr && writeBuffer != nullptr) {
+        LOGE("AudioStreamBuffered::%s(): both buffers are not NULL", __func__);
+        return ResultWithValue<int32_t>(Result::ErrorInternal);
+    }
+    if (getDirection() == Direction::Input && readBuffer == nullptr) {
+        LOGE("AudioStreamBuffered::%s(): readBuffer is NULL", __func__);
+        return ResultWithValue<int32_t>(Result::ErrorNull);
+    }
+    if (getDirection() == Direction::Output && writeBuffer == nullptr) {
+        LOGE("AudioStreamBuffered::%s(): writeBuffer is NULL", __func__);
         return ResultWithValue<int32_t>(Result::ErrorNull);
     }
     if (numFrames < 0) {
@@ -130,7 +140,8 @@
     }
 
     int32_t result = 0;
-    uint8_t *data = reinterpret_cast<uint8_t *>(buffer);
+    uint8_t *readData = reinterpret_cast<uint8_t *>(readBuffer);
+    const uint8_t *writeData = reinterpret_cast<const uint8_t *>(writeBuffer);
     int32_t framesLeft = numFrames;
     int64_t timeToQuit = 0;
     bool repeat = true;
@@ -144,18 +155,22 @@
     do {
         // read or write
         if (getDirection() == Direction::Input) {
-            result = mFifoBuffer->read(data, framesLeft);
+            result = mFifoBuffer->read(readData, framesLeft);
+            if (result > 0) {
+                readData += mFifoBuffer->convertFramesToBytes(result);
+                framesLeft -= result;
+            }
         } else {
             // between zero and capacity
             uint32_t fullFrames = mFifoBuffer->getFullFramesAvailable();
             // Do not write above threshold size.
             int32_t emptyFrames = getBufferSizeInFrames() - static_cast<int32_t>(fullFrames);
             int32_t framesToWrite = std::max(0, std::min(framesLeft, emptyFrames));
-            result = mFifoBuffer->write(data, framesToWrite);
-        }
-        if (result > 0) {
-            data += mFifoBuffer->convertFramesToBytes(result);
-            framesLeft -= result;
+            result = mFifoBuffer->write(writeData, framesToWrite);
+            if (result > 0) {
+                writeData += mFifoBuffer->convertFramesToBytes(result);
+                framesLeft -= result;
+            }
         }
 
         // If we need more data then sleep and try again.
@@ -211,8 +226,9 @@
     if (getDirection() == Direction::Input) {
         return ResultWithValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code?
     }
-    updateServiceFrameCounter();
-    return transfer(const_cast<void *>(buffer), numFrames, timeoutNanoseconds);
+    Result result = updateServiceFrameCounter();
+    if (result != Result::OK) return ResultWithValue<int32_t>(static_cast<Result>(result));
+    return transfer(nullptr, buffer, numFrames, timeoutNanoseconds);
 }
 
 // Read data from the FIFO that was written by the callback.
@@ -226,8 +242,9 @@
     if (getDirection() == Direction::Output) {
         return ResultWithValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code?
     }
-    updateServiceFrameCounter();
-    return transfer(buffer, numFrames, timeoutNanoseconds);
+    Result result = updateServiceFrameCounter();
+    if (result != Result::OK) return ResultWithValue<int32_t>(static_cast<Result>(result));
+    return transfer(buffer, nullptr, numFrames, timeoutNanoseconds);
 }
 
 // Only supported when we are not using a callback.
@@ -260,7 +277,7 @@
 
 bool AudioStreamBuffered::isXRunCountSupported() const {
     // XRun count is only supported if we're using blocking I/O (not callbacks)
-    return (getCallback() == nullptr);
+    return (!isDataCallbackSpecified());
 }
 
 } // namespace oboe
\ No newline at end of file
diff --git a/src/opensles/AudioStreamBuffered.h b/src/opensles/AudioStreamBuffered.h
index 5923e8d..d7e8885 100644
--- a/src/opensles/AudioStreamBuffered.h
+++ b/src/opensles/AudioStreamBuffered.h
@@ -60,7 +60,7 @@
     DataCallbackResult onDefaultCallback(void *audioData, int numFrames) override;
 
     // If there is no callback then we need a FIFO between the App and OpenSL ES.
-    bool usingFIFO() const { return getCallback() == nullptr; }
+    bool usingFIFO() const { return !isDataCallbackSpecified(); }
 
     virtual Result updateServiceFrameCounter() = 0;
 
@@ -74,7 +74,11 @@
     void markCallbackTime(int32_t numFrames);
 
     // Read or write to the FIFO.
-    ResultWithValue<int32_t> transfer(void *buffer, int32_t numFrames, int64_t timeoutNanoseconds);
+    // Only pass one pointer and set the other to nullptr.
+    ResultWithValue<int32_t> transfer(void *readBuffer,
+            const void *writeBuffer,
+            int32_t numFrames,
+            int64_t timeoutNanoseconds);
 
     void incrementXRunCount() {
         ++mXRunCount;
diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp
index 3af1a30..2b69935 100644
--- a/src/opensles/AudioStreamOpenSLES.cpp
+++ b/src/opensles/AudioStreamOpenSLES.cpp
@@ -134,6 +134,13 @@
 
     if (!usingFIFO()) {
         mBufferCapacityInFrames = mFramesPerBurst * kBufferQueueLength;
+        // Check for overflow.
+        if (mBufferCapacityInFrames <= 0) {
+            mBufferCapacityInFrames = 0;
+            LOGE("AudioStreamOpenSLES::open() numeric overflow because mFramesPerBurst = %d",
+                 mFramesPerBurst);
+            return Result::ErrorOutOfRange;
+        }
         mBufferSizeInFrames = mBufferCapacityInFrames;
     }
 
@@ -208,12 +215,6 @@
         LOGW("SessionId [AudioStreamBuilder::setSessionId()] "
              "is not supported on OpenSLES streams.");
     }
-
-    // Input Preset
-    if (mInputPreset != InputPreset::VoiceRecognition) {
-        LOGW("InputPreset [AudioStreamBuilder::setInputPreset()] "
-             "is not supported on OpenSLES streams.");
-    }
 }
 
 SLresult AudioStreamOpenSLES::configurePerformanceMode(SLAndroidConfigurationItf configItf) {
@@ -266,7 +267,8 @@
     return result;
 }
 
-Result AudioStreamOpenSLES::close() {
+// This is called under mLock.
+Result AudioStreamOpenSLES::close_l() {
     if (mState == StreamState::Closed) {
         return Result::ErrorClosed;
     }
@@ -381,7 +383,7 @@
         }
 
         // Did we timeout or did user ask for non-blocking?
-        if (timeoutNanoseconds <= 0) {
+        if (timeLeftNanos <= 0) {
             break;
         }
 
diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h
index 81fdc63..10a730b 100644
--- a/src/opensles/AudioStreamOpenSLES.h
+++ b/src/opensles/AudioStreamOpenSLES.h
@@ -50,7 +50,6 @@
     virtual ~AudioStreamOpenSLES() = default;
 
     virtual Result open() override;
-    virtual Result close() override;
 
     /**
      * Query the current state, eg. OBOE_STREAM_STATE_PAUSING
@@ -80,6 +79,9 @@
 
 protected:
 
+    // This must be called under mLock.
+    Result close_l();
+
     SLuint32 channelCountToChannelMaskDefault(int channelCount) const;
 
     virtual Result onBeforeDestroy() { return Result::OK; }
diff --git a/src/opensles/OpenSLESUtilities.cpp b/src/opensles/OpenSLESUtilities.cpp
index 071c0d0..4be23b3 100644
--- a/src/opensles/OpenSLESUtilities.cpp
+++ b/src/opensles/OpenSLESUtilities.cpp
@@ -24,42 +24,42 @@
 
 const char *getSLErrStr(SLresult code) {
     switch (code) {
-        case 0:
+        case SL_RESULT_SUCCESS:
             return "SL_RESULT_SUCCESS";
-        case 1:
-            return "SL_RESULT_PRECONDITIONS_VIOLATE";
-        case 2:
+        case SL_RESULT_PRECONDITIONS_VIOLATED:
+            return "SL_RESULT_PRECONDITIONS_VIOLATED";
+        case SL_RESULT_PARAMETER_INVALID:
             return "SL_RESULT_PARAMETER_INVALID";
-        case 3:
+        case SL_RESULT_MEMORY_FAILURE:
             return "SL_RESULT_MEMORY_FAILURE";
-        case 4:
+        case SL_RESULT_RESOURCE_ERROR:
             return "SL_RESULT_RESOURCE_ERROR";
-        case 5:
+        case SL_RESULT_RESOURCE_LOST:
             return "SL_RESULT_RESOURCE_LOST";
-        case 6:
+        case SL_RESULT_IO_ERROR:
             return "SL_RESULT_IO_ERROR";
-        case 7:
+        case SL_RESULT_BUFFER_INSUFFICIENT:
             return "SL_RESULT_BUFFER_INSUFFICIENT";
-        case 8:
+        case SL_RESULT_CONTENT_CORRUPTED:
             return "SL_RESULT_CONTENT_CORRUPTED";
-        case 9:
+        case SL_RESULT_CONTENT_UNSUPPORTED:
             return "SL_RESULT_CONTENT_UNSUPPORTED";
-        case 10:
+        case SL_RESULT_CONTENT_NOT_FOUND:
             return "SL_RESULT_CONTENT_NOT_FOUND";
-        case 11:
+        case SL_RESULT_PERMISSION_DENIED:
             return "SL_RESULT_PERMISSION_DENIED";
-        case 12:
+        case SL_RESULT_FEATURE_UNSUPPORTED:
             return "SL_RESULT_FEATURE_UNSUPPORTED";
-        case 13:
+        case SL_RESULT_INTERNAL_ERROR:
             return "SL_RESULT_INTERNAL_ERROR";
-        case 14:
+        case SL_RESULT_UNKNOWN_ERROR:
             return "SL_RESULT_UNKNOWN_ERROR";
-        case 15:
+        case SL_RESULT_OPERATION_ABORTED:
             return "SL_RESULT_OPERATION_ABORTED";
-        case 16:
+        case SL_RESULT_CONTROL_LOST:
             return "SL_RESULT_CONTROL_LOST";
         default:
-            return "Unknown error";
+            return "Unknown SL error";
     }
 }
 
diff --git a/tests/testStreamClosedMethods.cpp b/tests/testStreamClosedMethods.cpp
index a1f1105..cbb2191 100644
--- a/tests/testStreamClosedMethods.cpp
+++ b/tests/testStreamClosedMethods.cpp
@@ -19,15 +19,13 @@
 
 using namespace oboe;
 
-class MyCallback : public AudioStreamCallback {
+class MyCallback : public AudioStreamDataCallback {
 public:
     DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
         return DataCallbackResult::Continue;
     }
 };
 
-
-
 class StreamClosedReturnValues : public ::testing::Test {
 
 protected:
@@ -134,13 +132,13 @@
     ASSERT_EQ(mStream->getDeviceId(), d);
 }
 
-TEST_F(StreamClosedReturnValues, GetCallbackReturnsLastKnownValue) {
+TEST_F(StreamClosedReturnValues, GetDataCallbackReturnsLastKnownValue) {
 
-    AudioStreamCallback *callback = new MyCallback();
-    mBuilder.setCallback(callback);
+    AudioStreamDataCallback *callback = new MyCallback();
+    mBuilder.setDataCallback(callback);
     ASSERT_TRUE(openAndCloseStream());
 
-    AudioStreamCallback *callback2 = mStream->getCallback();
+    AudioStreamDataCallback *callback2 = mStream->getDataCallback();
     ASSERT_EQ(callback, callback2);
 }
 
diff --git a/tests/testStreamWaitState.cpp b/tests/testStreamWaitState.cpp
index 32fc50c..71dd5c9 100644
--- a/tests/testStreamWaitState.cpp
+++ b/tests/testStreamWaitState.cpp
@@ -57,12 +57,12 @@
         return (r == Result::OK || r == Result::ErrorClosed);
     }
 
-    void checkWaitZeroTimeout() {
+    // if zero then don't wait for a state change
+    void checkWaitForStateChangeTimeout(int64_t timeout = kTimeoutInNanos) {
         StreamState next = StreamState::Unknown;
-        int64_t timeout = 0; // don't wait for a state change
-		Result result = mStream->waitForStateChange(mStream->getState(), &next, timeout);
-		EXPECT_EQ(Result::ErrorTimeout, result);
-	}
+        Result result = mStream->waitForStateChange(mStream->getState(), &next, timeout);
+        EXPECT_EQ(Result::ErrorTimeout, result);
+    }
 
     void checkStopWhileWaiting() {
         StreamState next = StreamState::Unknown;
@@ -120,15 +120,16 @@
 
 };
 
+// Test return of error timeout when zero passed as the timeoutNanos.
 TEST_F(TestStreamWaitState, OutputLowWaitZero) {
     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
-    checkWaitZeroTimeout();
+    checkWaitForStateChangeTimeout(0);
     ASSERT_TRUE(closeStream());
 }
 
 TEST_F(TestStreamWaitState, OutputNoneWaitZero) {
     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None));
-    checkWaitZeroTimeout();
+    checkWaitForStateChangeTimeout(0);
     ASSERT_TRUE(closeStream());
 }
 
@@ -137,7 +138,7 @@
     builder.setPerformanceMode(PerformanceMode::LowLatency);
     builder.setAudioApi(AudioApi::OpenSLES);
     ASSERT_TRUE(openStream(builder));
-    checkWaitZeroTimeout();
+    checkWaitForStateChangeTimeout(0);
     ASSERT_TRUE(closeStream());
 }
 
@@ -146,10 +147,40 @@
     builder.setPerformanceMode(PerformanceMode::None);
     builder.setAudioApi(AudioApi::OpenSLES);
     ASSERT_TRUE(openStream(builder));
-    checkWaitZeroTimeout();
+    checkWaitForStateChangeTimeout(0);
     ASSERT_TRUE(closeStream());
 }
 
+// Test actual timeout.
+TEST_F(TestStreamWaitState, OutputLowWaitNonZero) {
+    ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
+    checkWaitForStateChangeTimeout();
+    ASSERT_TRUE(closeStream());
+}
+
+TEST_F(TestStreamWaitState, OutputNoneWaitNonZero) {
+    ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None));
+    checkWaitForStateChangeTimeout();
+    ASSERT_TRUE(closeStream());
+}
+
+TEST_F(TestStreamWaitState, OutputLowWaitNonZeroSLES) {
+    AudioStreamBuilder builder;
+    builder.setPerformanceMode(PerformanceMode::LowLatency);
+    builder.setAudioApi(AudioApi::OpenSLES);
+    ASSERT_TRUE(openStream(builder));
+    checkWaitForStateChangeTimeout();
+    ASSERT_TRUE(closeStream());
+}
+
+TEST_F(TestStreamWaitState, OutputNoneWaitNonZeroSLES) {
+    AudioStreamBuilder builder;
+    builder.setPerformanceMode(PerformanceMode::None);
+    builder.setAudioApi(AudioApi::OpenSLES);
+    ASSERT_TRUE(openStream(builder));
+    checkWaitForStateChangeTimeout();
+    ASSERT_TRUE(closeStream());
+}
 
 TEST_F(TestStreamWaitState, OutputLowStopWhileWaiting) {
     ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency));
@@ -215,4 +246,4 @@
     ASSERT_TRUE(openStream(builder));
     checkCloseWhileWaiting();
     ASSERT_TRUE(closeStream());
-}
\ No newline at end of file
+}