aboutsummaryrefslogtreecommitdiff
path: root/src/aaudio/AAudioLoader.h
blob: a07c53919b108d9656776b11a3f26c02a55a10f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright 2016 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 OBOE_AAUDIO_LOADER_H_
#define OBOE_AAUDIO_LOADER_H_

#include <unistd.h>
#include "oboe/Definitions.h"

// If the NDK is before O then define this in your build
// so that AAudio.h will not be included.
#ifdef OBOE_NO_INCLUDE_AAUDIO

// Define missing types from AAudio.h
typedef int32_t aaudio_stream_state_t;
typedef int32_t aaudio_direction_t;
typedef int32_t aaudio_format_t;
typedef int32_t aaudio_data_callback_result_t;
typedef int32_t aaudio_result_t;
typedef int32_t aaudio_sharing_mode_t;
typedef int32_t aaudio_performance_mode_t;

typedef struct AAudioStreamStruct         AAudioStream;
typedef struct AAudioStreamBuilderStruct  AAudioStreamBuilder;

typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)(
        AAudioStream *stream,
        void *userData,
        void *audioData,
        int32_t numFrames);

typedef void (*AAudioStream_errorCallback)(
        AAudioStream *stream,
        void *userData,
        aaudio_result_t error);

// These were defined in P
typedef int32_t aaudio_usage_t;
typedef int32_t aaudio_content_type_t;
typedef int32_t aaudio_input_preset_t;
typedef int32_t aaudio_session_id_t;

// There are a few definitions used by Oboe.
#define AAUDIO_OK                      static_cast<aaudio_result_t>(Result::OK)
#define AAUDIO_ERROR_TIMEOUT           static_cast<aaudio_result_t>(Result::ErrorTimeout)
#define AAUDIO_STREAM_STATE_STARTING   static_cast<aaudio_stream_state_t>(StreamState::Starting)
#define AAUDIO_STREAM_STATE_STARTED    static_cast<aaudio_stream_state_t>(StreamState::Started)
#else
#include <aaudio/AAudio.h>
#include <android/ndk-version.h>
#endif

#ifndef __NDK_MAJOR__
#define __NDK_MAJOR__ 0
#endif

namespace oboe {

/**
 * The AAudio API was not available in early versions of Android.
 * To avoid linker errors, we dynamically link with the functions by name using dlsym().
 * On older versions this linkage will safely fail.
 */
class AAudioLoader {
  public:
    // Use signatures for common functions.
    // Key to letter abbreviations.
    // S = Stream
    // B = Builder
    // I = int32_t
    // L = int64_t
    // T = sTate
    // K = clocKid_t
    // P = Pointer to following data type
    // C = Const prefix
    // H = cHar
    typedef int32_t  (*signature_I_PPB)(AAudioStreamBuilder **builder);

    typedef const char * (*signature_CPH_I)(int32_t);

    typedef int32_t (*signature_I_PBPPS)(AAudioStreamBuilder *,
                                      AAudioStream **stream);  // AAudioStreamBuilder_open()

    typedef int32_t (*signature_I_PB)(AAudioStreamBuilder *);  // AAudioStreamBuilder_delete()
    // AAudioStreamBuilder_setSampleRate()
    typedef void    (*signature_V_PBI)(AAudioStreamBuilder *, int32_t);

    typedef int32_t (*signature_I_PS)(AAudioStream *);  // AAudioStream_getSampleRate()
    typedef int64_t (*signature_L_PS)(AAudioStream *);  // AAudioStream_getFramesRead()
    // AAudioStream_setBufferSizeInFrames()
    typedef int32_t (*signature_I_PSI)(AAudioStream *, int32_t);

    typedef void    (*signature_V_PBPDPV)(AAudioStreamBuilder *,
                                          AAudioStream_dataCallback,
                                          void *);

    typedef void    (*signature_V_PBPEPV)(AAudioStreamBuilder *,
                                          AAudioStream_errorCallback,
                                          void *);

    typedef aaudio_format_t (*signature_F_PS)(AAudioStream *stream);

    typedef int32_t (*signature_I_PSPVIL)(AAudioStream *, void *, int32_t, int64_t);
    typedef int32_t (*signature_I_PSCPVIL)(AAudioStream *, const void *, int32_t, int64_t);

    typedef int32_t (*signature_I_PSTPTL)(AAudioStream *,
                                          aaudio_stream_state_t,
                                          aaudio_stream_state_t *,
                                          int64_t);

    typedef int32_t (*signature_I_PSKPLPL)(AAudioStream *, clockid_t, int64_t *, int64_t *);

    typedef bool    (*signature_B_PS)(AAudioStream *);

    static AAudioLoader* getInstance(); // singleton

    /**
     * Open the AAudio shared library and load the function pointers.
     * This can be called multiple times.
     * It should only be called from one thread.
     *
     * The destructor will clean up after the open.
     *
     * @return 0 if successful or negative error.
     */
    int open();

    void *getLibHandle() const { return mLibHandle; }

    // Function pointers into the AAudio shared library.
    signature_I_PPB   createStreamBuilder = nullptr;

    signature_I_PBPPS builder_openStream = nullptr;

    signature_V_PBI builder_setBufferCapacityInFrames = nullptr;
    signature_V_PBI builder_setChannelCount = nullptr;
    signature_V_PBI builder_setDeviceId = nullptr;
    signature_V_PBI builder_setDirection = nullptr;
    signature_V_PBI builder_setFormat = nullptr;
    signature_V_PBI builder_setFramesPerDataCallback = nullptr;
    signature_V_PBI builder_setPerformanceMode = nullptr;
    signature_V_PBI builder_setSampleRate = nullptr;
    signature_V_PBI builder_setSharingMode = nullptr;

    signature_V_PBI builder_setUsage = nullptr;
    signature_V_PBI builder_setContentType = nullptr;
    signature_V_PBI builder_setInputPreset = nullptr;
    signature_V_PBI builder_setSessionId = nullptr;

    signature_V_PBPDPV  builder_setDataCallback = nullptr;
    signature_V_PBPEPV  builder_setErrorCallback = nullptr;

    signature_I_PB      builder_delete = nullptr;

    signature_F_PS      stream_getFormat = nullptr;

    signature_I_PSPVIL  stream_read = nullptr;
    signature_I_PSCPVIL stream_write = nullptr;

    signature_I_PSTPTL  stream_waitForStateChange = nullptr;

    signature_I_PSKPLPL stream_getTimestamp = nullptr;

    signature_I_PS   stream_close = nullptr;

    signature_I_PS   stream_getChannelCount = nullptr;
    signature_I_PS   stream_getDeviceId = nullptr;

    signature_I_PS   stream_getBufferSize = nullptr;
    signature_I_PS   stream_getBufferCapacity = nullptr;
    signature_I_PS   stream_getFramesPerBurst = nullptr;
    signature_I_PS   stream_getState = nullptr;
    signature_I_PS   stream_getPerformanceMode = nullptr;
    signature_I_PS   stream_getSampleRate = nullptr;
    signature_I_PS   stream_getSharingMode = nullptr;
    signature_I_PS   stream_getXRunCount = nullptr;

    signature_I_PSI  stream_setBufferSize = nullptr;
    signature_I_PS   stream_requestStart = nullptr;
    signature_I_PS   stream_requestPause = nullptr;
    signature_I_PS   stream_requestFlush = nullptr;
    signature_I_PS   stream_requestStop = nullptr;

    signature_L_PS   stream_getFramesRead = nullptr;
    signature_L_PS   stream_getFramesWritten = nullptr;

    signature_CPH_I  convertResultToText = nullptr;

    signature_I_PS   stream_getUsage = nullptr;
    signature_I_PS   stream_getContentType = nullptr;
    signature_I_PS   stream_getInputPreset = nullptr;
    signature_I_PS   stream_getSessionId = nullptr;

  private:
    AAudioLoader() {}
    ~AAudioLoader();

    // Load function pointers for specific signatures.
    signature_I_PPB     load_I_PPB(const char *name);
    signature_CPH_I     load_CPH_I(const char *name);
    signature_V_PBI     load_V_PBI(const char *name);
    signature_V_PBPDPV  load_V_PBPDPV(const char *name);
    signature_V_PBPEPV  load_V_PBPEPV(const char *name);
    signature_I_PB      load_I_PB(const char *name);
    signature_I_PBPPS   load_I_PBPPS(const char *name);
    signature_I_PS      load_I_PS(const char *name);
    signature_L_PS      load_L_PS(const char *name);
    signature_F_PS      load_F_PS(const char *name);
    signature_B_PS      load_B_PS(const char *name);
    signature_I_PSI     load_I_PSI(const char *name);
    signature_I_PSPVIL  load_I_PSPVIL(const char *name);
    signature_I_PSCPVIL load_I_PSCPVIL(const char *name);
    signature_I_PSTPTL  load_I_PSTPTL(const char *name);
    signature_I_PSKPLPL load_I_PSKPLPL(const char *name);

    void *mLibHandle = nullptr;
};

} // namespace oboe

#endif //OBOE_AAUDIO_LOADER_H_