Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Mikhail Naganov | deffe41 | 2017-09-18 17:34:51 -0700 | [diff] [blame] | 17 | #ifndef OBOE_AAUDIO_LOADER_H_ |
| 18 | #define OBOE_AAUDIO_LOADER_H_ |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 19 | |
| 20 | #include <unistd.h> |
Don Turner | 3bf32ae | 2017-11-27 13:25:05 +0000 | [diff] [blame] | 21 | #include "oboe/Definitions.h" |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 22 | |
Phil Burk | 10619f6 | 2019-03-29 09:02:30 -0700 | [diff] [blame] | 23 | // If the NDK is before O then define this in your build |
| 24 | // so that AAudio.h will not be included. |
| 25 | #ifdef OBOE_NO_INCLUDE_AAUDIO |
| 26 | |
| 27 | // Define missing types from AAudio.h |
| 28 | typedef int32_t aaudio_stream_state_t; |
| 29 | typedef int32_t aaudio_direction_t; |
| 30 | typedef int32_t aaudio_format_t; |
| 31 | typedef int32_t aaudio_data_callback_result_t; |
| 32 | typedef int32_t aaudio_result_t; |
| 33 | typedef int32_t aaudio_sharing_mode_t; |
| 34 | typedef int32_t aaudio_performance_mode_t; |
| 35 | |
Phil Burk | 4e7259a | 2019-03-28 19:04:29 -0700 | [diff] [blame] | 36 | typedef struct AAudioStreamStruct AAudioStream; |
| 37 | typedef struct AAudioStreamBuilderStruct AAudioStreamBuilder; |
| 38 | |
| 39 | typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)( |
| 40 | AAudioStream *stream, |
| 41 | void *userData, |
| 42 | void *audioData, |
| 43 | int32_t numFrames); |
| 44 | |
| 45 | typedef void (*AAudioStream_errorCallback)( |
| 46 | AAudioStream *stream, |
| 47 | void *userData, |
| 48 | aaudio_result_t error); |
Phil Burk | 10619f6 | 2019-03-29 09:02:30 -0700 | [diff] [blame] | 49 | |
| 50 | // These were defined in P |
| 51 | typedef int32_t aaudio_usage_t; |
| 52 | typedef int32_t aaudio_content_type_t; |
| 53 | typedef int32_t aaudio_input_preset_t; |
| 54 | typedef int32_t aaudio_session_id_t; |
Haibo Huang | c0d5f47 | 2021-02-09 16:44:15 -0800 | [diff] [blame^] | 55 | |
| 56 | // There are a few definitions used by Oboe. |
| 57 | #define AAUDIO_OK static_cast<aaudio_result_t>(Result::OK) |
| 58 | #define AAUDIO_ERROR_TIMEOUT static_cast<aaudio_result_t>(Result::ErrorTimeout) |
| 59 | #define AAUDIO_STREAM_STATE_STARTING static_cast<aaudio_stream_state_t>(StreamState::Starting) |
| 60 | #define AAUDIO_STREAM_STATE_STARTED static_cast<aaudio_stream_state_t>(StreamState::Started) |
Phil Burk | 10619f6 | 2019-03-29 09:02:30 -0700 | [diff] [blame] | 61 | #else |
| 62 | #include <aaudio/AAudio.h> |
| 63 | #include <android/ndk-version.h> |
| 64 | #endif |
| 65 | |
| 66 | #ifndef __NDK_MAJOR__ |
| 67 | #define __NDK_MAJOR__ 0 |
Phil Burk | 4e7259a | 2019-03-28 19:04:29 -0700 | [diff] [blame] | 68 | #endif |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 69 | |
Don Turner | 3bf32ae | 2017-11-27 13:25:05 +0000 | [diff] [blame] | 70 | namespace oboe { |
| 71 | |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 72 | /** |
| 73 | * The AAudio API was not available in early versions of Android. |
| 74 | * To avoid linker errors, we dynamically link with the functions by name using dlsym(). |
| 75 | * On older versions this linkage will safely fail. |
| 76 | */ |
| 77 | class AAudioLoader { |
Mikhail Naganov | 455027e | 2017-09-20 09:16:23 -0700 | [diff] [blame] | 78 | public: |
| 79 | // Use signatures for common functions. |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 80 | // Key to letter abbreviations. |
| 81 | // S = Stream |
| 82 | // B = Builder |
| 83 | // I = int32_t |
| 84 | // L = int64_t |
| 85 | // T = sTate |
| 86 | // K = clocKid_t |
| 87 | // P = Pointer to following data type |
| 88 | // C = Const prefix |
| 89 | // H = cHar |
| 90 | typedef int32_t (*signature_I_PPB)(AAudioStreamBuilder **builder); |
| 91 | |
| 92 | typedef const char * (*signature_CPH_I)(int32_t); |
| 93 | |
| 94 | typedef int32_t (*signature_I_PBPPS)(AAudioStreamBuilder *, |
| 95 | AAudioStream **stream); // AAudioStreamBuilder_open() |
Mikhail Naganov | 455027e | 2017-09-20 09:16:23 -0700 | [diff] [blame] | 96 | |
| 97 | typedef int32_t (*signature_I_PB)(AAudioStreamBuilder *); // AAudioStreamBuilder_delete() |
| 98 | // AAudioStreamBuilder_setSampleRate() |
| 99 | typedef void (*signature_V_PBI)(AAudioStreamBuilder *, int32_t); |
| 100 | |
| 101 | typedef int32_t (*signature_I_PS)(AAudioStream *); // AAudioStream_getSampleRate() |
| 102 | typedef int64_t (*signature_L_PS)(AAudioStream *); // AAudioStream_getFramesRead() |
| 103 | // AAudioStream_setBufferSizeInFrames() |
| 104 | typedef int32_t (*signature_I_PSI)(AAudioStream *, int32_t); |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 105 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 106 | typedef void (*signature_V_PBPDPV)(AAudioStreamBuilder *, |
| 107 | AAudioStream_dataCallback, |
| 108 | void *); |
| 109 | |
| 110 | typedef void (*signature_V_PBPEPV)(AAudioStreamBuilder *, |
| 111 | AAudioStream_errorCallback, |
| 112 | void *); |
| 113 | |
| 114 | typedef aaudio_format_t (*signature_F_PS)(AAudioStream *stream); |
| 115 | |
| 116 | typedef int32_t (*signature_I_PSPVIL)(AAudioStream *, void *, int32_t, int64_t); |
| 117 | typedef int32_t (*signature_I_PSCPVIL)(AAudioStream *, const void *, int32_t, int64_t); |
| 118 | |
| 119 | typedef int32_t (*signature_I_PSTPTL)(AAudioStream *, |
| 120 | aaudio_stream_state_t, |
| 121 | aaudio_stream_state_t *, |
| 122 | int64_t); |
| 123 | |
| 124 | typedef int32_t (*signature_I_PSKPLPL)(AAudioStream *, clockid_t, int64_t *, int64_t *); |
| 125 | |
| 126 | typedef bool (*signature_B_PS)(AAudioStream *); |
| 127 | |
Mikhail Naganov | deffe41 | 2017-09-18 17:34:51 -0700 | [diff] [blame] | 128 | static AAudioLoader* getInstance(); // singleton |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 129 | |
| 130 | /** |
| 131 | * Open the AAudio shared library and load the function pointers. |
| 132 | * This can be called multiple times. |
| 133 | * It should only be called from one thread. |
| 134 | * |
Phil Burk | 65983d6 | 2018-11-21 16:38:32 -0800 | [diff] [blame] | 135 | * The destructor will clean up after the open. |
| 136 | * |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 137 | * @return 0 if successful or negative error. |
| 138 | */ |
| 139 | int open(); |
| 140 | |
Haibo Huang | c0d5f47 | 2021-02-09 16:44:15 -0800 | [diff] [blame^] | 141 | void *getLibHandle() const { return mLibHandle; } |
| 142 | |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 143 | // Function pointers into the AAudio shared library. |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 144 | signature_I_PPB createStreamBuilder = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 145 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 146 | signature_I_PBPPS builder_openStream = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 147 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 148 | signature_V_PBI builder_setBufferCapacityInFrames = nullptr; |
| 149 | signature_V_PBI builder_setChannelCount = nullptr; |
| 150 | signature_V_PBI builder_setDeviceId = nullptr; |
| 151 | signature_V_PBI builder_setDirection = nullptr; |
| 152 | signature_V_PBI builder_setFormat = nullptr; |
| 153 | signature_V_PBI builder_setFramesPerDataCallback = nullptr; |
| 154 | signature_V_PBI builder_setPerformanceMode = nullptr; |
| 155 | signature_V_PBI builder_setSampleRate = nullptr; |
| 156 | signature_V_PBI builder_setSharingMode = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 157 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 158 | signature_V_PBI builder_setUsage = nullptr; |
| 159 | signature_V_PBI builder_setContentType = nullptr; |
| 160 | signature_V_PBI builder_setInputPreset = nullptr; |
| 161 | signature_V_PBI builder_setSessionId = nullptr; |
Phil Burk | c30bbe6 | 2018-05-21 17:06:21 -0700 | [diff] [blame] | 162 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 163 | signature_V_PBPDPV builder_setDataCallback = nullptr; |
| 164 | signature_V_PBPEPV builder_setErrorCallback = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 165 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 166 | signature_I_PB builder_delete = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 167 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 168 | signature_F_PS stream_getFormat = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 169 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 170 | signature_I_PSPVIL stream_read = nullptr; |
| 171 | signature_I_PSCPVIL stream_write = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 172 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 173 | signature_I_PSTPTL stream_waitForStateChange = nullptr; |
Mikhail Naganov | f8a24d6 | 2017-09-19 14:11:43 -0700 | [diff] [blame] | 174 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 175 | signature_I_PSKPLPL stream_getTimestamp = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 176 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 177 | signature_I_PS stream_close = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 178 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 179 | signature_I_PS stream_getChannelCount = nullptr; |
| 180 | signature_I_PS stream_getDeviceId = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 181 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 182 | signature_I_PS stream_getBufferSize = nullptr; |
| 183 | signature_I_PS stream_getBufferCapacity = nullptr; |
| 184 | signature_I_PS stream_getFramesPerBurst = nullptr; |
| 185 | signature_I_PS stream_getState = nullptr; |
| 186 | signature_I_PS stream_getPerformanceMode = nullptr; |
| 187 | signature_I_PS stream_getSampleRate = nullptr; |
| 188 | signature_I_PS stream_getSharingMode = nullptr; |
| 189 | signature_I_PS stream_getXRunCount = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 190 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 191 | signature_I_PSI stream_setBufferSize = nullptr; |
| 192 | signature_I_PS stream_requestStart = nullptr; |
| 193 | signature_I_PS stream_requestPause = nullptr; |
| 194 | signature_I_PS stream_requestFlush = nullptr; |
| 195 | signature_I_PS stream_requestStop = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 196 | |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 197 | signature_L_PS stream_getFramesRead = nullptr; |
| 198 | signature_L_PS stream_getFramesWritten = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 199 | |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 200 | signature_CPH_I convertResultToText = nullptr; |
Phil Burk | 7888992 | 2018-12-17 16:49:47 -0800 | [diff] [blame] | 201 | |
| 202 | signature_I_PS stream_getUsage = nullptr; |
| 203 | signature_I_PS stream_getContentType = nullptr; |
| 204 | signature_I_PS stream_getInputPreset = nullptr; |
| 205 | signature_I_PS stream_getSessionId = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 206 | |
Mikhail Naganov | 455027e | 2017-09-20 09:16:23 -0700 | [diff] [blame] | 207 | private: |
Mikhail Naganov | deffe41 | 2017-09-18 17:34:51 -0700 | [diff] [blame] | 208 | AAudioLoader() {} |
Mikhail Naganov | 455027e | 2017-09-20 09:16:23 -0700 | [diff] [blame] | 209 | ~AAudioLoader(); |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 210 | |
| 211 | // Load function pointers for specific signatures. |
Phil Burk | 6606224 | 2019-02-04 11:37:37 -0800 | [diff] [blame] | 212 | signature_I_PPB load_I_PPB(const char *name); |
| 213 | signature_CPH_I load_CPH_I(const char *name); |
| 214 | signature_V_PBI load_V_PBI(const char *name); |
| 215 | signature_V_PBPDPV load_V_PBPDPV(const char *name); |
| 216 | signature_V_PBPEPV load_V_PBPEPV(const char *name); |
| 217 | signature_I_PB load_I_PB(const char *name); |
| 218 | signature_I_PBPPS load_I_PBPPS(const char *name); |
| 219 | signature_I_PS load_I_PS(const char *name); |
| 220 | signature_L_PS load_L_PS(const char *name); |
| 221 | signature_F_PS load_F_PS(const char *name); |
| 222 | signature_B_PS load_B_PS(const char *name); |
| 223 | signature_I_PSI load_I_PSI(const char *name); |
| 224 | signature_I_PSPVIL load_I_PSPVIL(const char *name); |
| 225 | signature_I_PSCPVIL load_I_PSCPVIL(const char *name); |
| 226 | signature_I_PSTPTL load_I_PSTPTL(const char *name); |
| 227 | signature_I_PSKPLPL load_I_PSKPLPL(const char *name); |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 228 | |
| 229 | void *mLibHandle = nullptr; |
Don Turner | ca6f91a | 2017-09-05 14:52:39 +0100 | [diff] [blame] | 230 | }; |
| 231 | |
Don Turner | 3bf32ae | 2017-11-27 13:25:05 +0000 | [diff] [blame] | 232 | } // namespace oboe |
| 233 | |
Mikhail Naganov | deffe41 | 2017-09-18 17:34:51 -0700 | [diff] [blame] | 234 | #endif //OBOE_AAUDIO_LOADER_H_ |