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
17 #ifndef UTILITY_AAUDIO_UTILITIES_H
18 #define UTILITY_AAUDIO_UTILITIES_H
19
20 #include <algorithm>
21 #include <functional>
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include <utils/Errors.h>
27 #include <system/audio.h>
28
29 #include "aaudio/AAudio.h"
30
31 /**
32 * Convert an AAudio result into the closest matching Android status.
33 */
34 android::status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result);
35
36 /**
37 * Convert an Android status into the closest matching AAudio result.
38 */
39 aaudio_result_t AAudioConvert_androidToAAudioResult(android::status_t status);
40
41 /**
42 * Convert an aaudio_session_id_t to a value that is safe to pass to AudioFlinger.
43 * @param sessionId
44 * @return safe value
45 */
46 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
47
48 /**
49 * Calculate the number of bytes and prevent numeric overflow.
50 * The *sizeInBytes will be set to zero if there is an error.
51 *
52 * @param numFrames frame count
53 * @param bytesPerFrame size of a frame in bytes
54 * @param sizeInBytes pointer to a variable to receive total size in bytes
55 * @return AAUDIO_OK or negative error, eg. AAUDIO_ERROR_OUT_OF_RANGE
56 */
57 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
58 int32_t bytesPerFrame,
59 int32_t *sizeInBytes);
60
61 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudio_format);
62
63 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
64
65
66 /**
67 * Note that this function does not validate the passed in value.
68 * That is done somewhere else.
69 * @return internal value
70 */
71
72 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage);
73
74 /**
75 * Note that this function does not validate the passed in value.
76 * That is done somewhere else.
77 * @return internal value
78 */
79 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType);
80
81 /**
82 * Note that this function does not validate the passed in value.
83 * That is done somewhere else.
84 * @return internal audio source
85 */
86 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
87
88 /**
89 * Note that this function does not validate the passed in value.
90 * That is done somewhere else.
91 * @return internal audio flags mask
92 */
93 audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
94 aaudio_allowed_capture_policy_t policy,
95 aaudio_spatialization_behavior_t spatializationBehavior,
96 bool isContentSpatialized);
97
98 audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
99 bool privacySensitive);
100
101 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelLayoutMask(
102 aaudio_channel_mask_t channelMask, bool isInput);
103
104 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelLayoutMask(
105 audio_channel_mask_t channelMask, bool isInput);
106
107 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelIndexMask(
108 audio_channel_mask_t channelMask);
109
110 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelIndexMask(
111 aaudio_channel_mask_t channelMask);
112
113 aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelMask(
114 audio_channel_mask_t channelMask, bool isInput, bool indexMaskRequired);
115
116 audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelMask(
117 aaudio_channel_mask_t channelMask, bool isInput);
118
119 bool AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask);
120
121 int32_t AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask);
122
123 aaudio_channel_mask_t AAudioConvert_channelCountToMask(int32_t channelCount);
124
125 audio_channel_mask_t AAudio_getChannelMaskForOpen(
126 aaudio_channel_mask_t channelMask, int32_t samplesPerFrame, bool isInput);
127
128 // Note that this code may be replaced by Settings or by some other system configuration tool.
129
130 /**
131 * Read a system property that specifies the number of extra microseconds that a thread
132 * should sleep when waiting for another thread to service a FIFO. This is used
133 * to avoid the waking thread from being overly optimistic about the other threads
134 * wakeup timing. This value should be set high enough to cover typical scheduling jitter
135 * for a real-time thread.
136 *
137 * @return number of microseconds to delay the wakeup.
138 */
139 int32_t AAudioProperty_getWakeupDelayMicros();
140 #define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec"
141
142 /**
143 * Read a system property that specifies the minimum sleep time when polling the FIFO.
144 *
145 * @return minimum number of microseconds to sleep.
146 */
147 int32_t AAudioProperty_getMinimumSleepMicros();
148 #define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec"
149
150 /**
151 * Read a system property that specifies an offset that will be added to MMAP timestamps.
152 * This can be used to correct bias in the timestamp.
153 * It can also be used to analyze the time distribution of the timestamp
154 * by progressively modifying the offset and listening for glitches.
155 *
156 * @return number of microseconds to offset the time part of an MMAP timestamp
157 */
158 int32_t AAudioProperty_getInputMMapOffsetMicros();
159 #define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC "aaudio.in_mmap_offset_usec"
160
161 int32_t AAudioProperty_getOutputMMapOffsetMicros();
162 #define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC "aaudio.out_mmap_offset_usec"
163
164 // These are powers of two that can be combined as a bit mask.
165 // AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM must be enabled before the stream is opened.
166 #define AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM 1
167 #define AAUDIO_LOG_RESERVED_2 2
168 #define AAUDIO_LOG_RESERVED_4 4
169 #define AAUDIO_LOG_RESERVED_8 8
170
171 /**
172 * Use a mask to enable various logs in AAudio.
173 * @return mask that enables various AAudio logs, such as AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM
174 */
175 int32_t AAudioProperty_getLogMask();
176 #define AAUDIO_PROP_LOG_MASK "aaudio.log_mask"
177
178 /**
179 * Is flush allowed for the given state?
180 * @param state
181 * @return AAUDIO_OK if allowed or an error
182 */
183 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state);
184
185 /**
186 * Try a function f until it returns true.
187 *
188 * The function is always called at least once.
189 *
190 * @param f the function to evaluate, which returns a bool.
191 * @param times the number of times to evaluate f.
192 * @param sleepMs the sleep time per check of f, if greater than 0.
193 * @return true if f() eventually returns true.
194 */
AAudio_tryUntilTrue(const std::function<bool ()> & f,int times,int sleepMs)195 static inline bool AAudio_tryUntilTrue(
196 const std::function<bool()>& f, int times, int sleepMs) {
197 static const useconds_t US_PER_MS = 1000;
198
199 sleepMs = std::max(sleepMs, 0);
200 for (;;) {
201 if (f()) return true;
202 if (times <= 1) return false;
203 --times;
204 usleep(sleepMs * US_PER_MS);
205 }
206 }
207
208
209 /**
210 * Simple double buffer for a structure that can be written occasionally and read occasionally.
211 * This allows a SINGLE writer with multiple readers.
212 *
213 * It is OK if the FIFO overflows and we lose old values.
214 * It is also OK if we read an old value.
215 * Thread may return a non-atomic result if the other thread is rapidly writing
216 * new values on another core.
217 */
218 template <class T>
219 class SimpleDoubleBuffer {
220 public:
SimpleDoubleBuffer()221 SimpleDoubleBuffer()
222 : mValues() {}
223
224 __attribute__((no_sanitize("integer")))
write(T value)225 void write(T value) {
226 int index = mCounter.load() & 1;
227 mValues[index] = value;
228 mCounter++; // Increment AFTER updating storage, OK if it wraps.
229 }
230
231 /**
232 * This should only be called by the same thread that calls write() or when
233 * no other thread is calling write.
234 */
clear()235 void clear() {
236 mCounter.store(0);
237 }
238
read()239 T read() const {
240 T result;
241 int before;
242 int after;
243 int timeout = 3;
244 do {
245 // Check to see if a write occurred while were reading.
246 before = mCounter.load();
247 int index = (before & 1) ^ 1;
248 result = mValues[index];
249 after = mCounter.load();
250 } while ((after != before) && (after > 0) && (--timeout > 0));
251 return result;
252 }
253
254 /**
255 * @return true if at least one value has been written
256 */
isValid()257 bool isValid() const {
258 return mCounter.load() > 0;
259 }
260
261 private:
262 T mValues[2];
263 std::atomic<int> mCounter{0};
264 };
265
266 class Timestamp {
267 public:
268 Timestamp() = default;
Timestamp(int64_t position,int64_t nanoseconds)269 Timestamp(int64_t position, int64_t nanoseconds)
270 : mPosition(position)
271 , mNanoseconds(nanoseconds) {}
272
getPosition()273 int64_t getPosition() const { return mPosition; }
274
getNanoseconds()275 int64_t getNanoseconds() const { return mNanoseconds; }
276
277 private:
278 // These cannot be const because we need to implement the copy assignment operator.
279 int64_t mPosition{0};
280 int64_t mNanoseconds{0};
281 };
282
283
284 /**
285 * Pass a request to another thread.
286 * This is used when one thread, A, wants another thread, B, to do something.
287 * A naive approach would be for A to set a flag and for B to clear it when done.
288 * But that creates a race condition. This technique avoids the race condition.
289 *
290 * Assumes only one requester and one acknowledger.
291 */
292 class AtomicRequestor {
293 public:
294
295 __attribute__((no_sanitize("integer")))
request()296 void request() {
297 mRequested++;
298 }
299
300 __attribute__((no_sanitize("integer")))
isRequested()301 bool isRequested() {
302 return (mRequested.load() - mAcknowledged.load()) > 0;
303 }
304
305 __attribute__((no_sanitize("integer")))
acknowledge()306 void acknowledge() {
307 mAcknowledged++;
308 }
309
310 private:
311 std::atomic<int> mRequested{0};
312 std::atomic<int> mAcknowledged{0};
313 };
314
315 enum {
316 /**
317 * Audio channel index mask, only used internally.
318 */
319 AAUDIO_CHANNEL_BIT_INDEX = 0x80000000,
320 AAUDIO_CHANNEL_INDEX_MASK_1 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 1) - 1,
321 AAUDIO_CHANNEL_INDEX_MASK_2 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 2) - 1,
322 AAUDIO_CHANNEL_INDEX_MASK_3 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 3) - 1,
323 AAUDIO_CHANNEL_INDEX_MASK_4 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 4) - 1,
324 AAUDIO_CHANNEL_INDEX_MASK_5 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 5) - 1,
325 AAUDIO_CHANNEL_INDEX_MASK_6 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 6) - 1,
326 AAUDIO_CHANNEL_INDEX_MASK_7 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 7) - 1,
327 AAUDIO_CHANNEL_INDEX_MASK_8 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 8) - 1,
328 AAUDIO_CHANNEL_INDEX_MASK_9 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 9) - 1,
329 AAUDIO_CHANNEL_INDEX_MASK_10 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 10) - 1,
330 AAUDIO_CHANNEL_INDEX_MASK_11 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 11) - 1,
331 AAUDIO_CHANNEL_INDEX_MASK_12 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 12) - 1,
332 AAUDIO_CHANNEL_INDEX_MASK_13 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 13) - 1,
333 AAUDIO_CHANNEL_INDEX_MASK_14 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 14) - 1,
334 AAUDIO_CHANNEL_INDEX_MASK_15 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 15) - 1,
335 AAUDIO_CHANNEL_INDEX_MASK_16 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 16) - 1,
336 AAUDIO_CHANNEL_INDEX_MASK_17 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 17) - 1,
337 AAUDIO_CHANNEL_INDEX_MASK_18 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 18) - 1,
338 AAUDIO_CHANNEL_INDEX_MASK_19 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 19) - 1,
339 AAUDIO_CHANNEL_INDEX_MASK_20 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 20) - 1,
340 AAUDIO_CHANNEL_INDEX_MASK_21 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 21) - 1,
341 AAUDIO_CHANNEL_INDEX_MASK_22 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 22) - 1,
342 AAUDIO_CHANNEL_INDEX_MASK_23 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 23) - 1,
343 AAUDIO_CHANNEL_INDEX_MASK_24 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 24) - 1,
344 };
345
346 #endif //UTILITY_AAUDIO_UTILITIES_H
347