blob: 5eda30c42f2ed12008cb16c0aa46c368e81e8bff [file] [log] [blame]
Phil Burk5ed503c2017-02-01 09:38:15 -08001/*
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
Andy Hung47c5e532017-06-26 18:28:00 -070020#include <algorithm>
21#include <functional>
Phil Burk5ed503c2017-02-01 09:38:15 -080022#include <stdint.h>
23#include <sys/types.h>
Tom Cherry7ae78252020-04-13 15:20:50 -070024#include <unistd.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080025
26#include <utils/Errors.h>
Kevin Rocard6d7582e2018-01-11 19:28:14 -080027#include <system/audio.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080028
Phil Burka4eb0d82017-04-12 15:44:06 -070029#include "aaudio/AAudio.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080030
31/**
32 * Convert an AAudio result into the closest matching Android status.
33 */
34android::status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result);
35
36/**
37 * Convert an Android status into the closest matching AAudio result.
38 */
39aaudio_result_t AAudioConvert_androidToAAudioResult(android::status_t status);
40
Phil Burke572f462017-04-20 13:03:19 -070041/**
Phil Burk4e1af9f2018-01-03 15:54:35 -080042 * Convert an aaudio_session_id_t to a value that is safe to pass to AudioFlinger.
43 * @param sessionId
44 * @return safe value
45 */
46audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
47
48/**
Phil Burk5ed503c2017-02-01 09:38:15 -080049 * Calculate the number of bytes and prevent numeric overflow.
Phil Burk7f680132018-03-12 14:48:06 -070050 * The *sizeInBytes will be set to zero if there is an error.
51 *
Phil Burk5ed503c2017-02-01 09:38:15 -080052 * @param numFrames frame count
53 * @param bytesPerFrame size of a frame in bytes
Phil Burk7f680132018-03-12 14:48:06 -070054 * @param sizeInBytes pointer to a variable to receive total size in bytes
Phil Burk5ed503c2017-02-01 09:38:15 -080055 * @return AAUDIO_OK or negative error, eg. AAUDIO_ERROR_OUT_OF_RANGE
56 */
Phil Burk3316d5e2017-02-15 11:23:01 -080057int32_t AAudioConvert_framesToBytes(int32_t numFrames,
Phil Burk7f680132018-03-12 14:48:06 -070058 int32_t bytesPerFrame,
59 int32_t *sizeInBytes);
Phil Burk5ed503c2017-02-01 09:38:15 -080060
Phil Burk9dca9822017-05-26 14:27:43 -070061audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudio_format);
Phil Burk5ed503c2017-02-01 09:38:15 -080062
Phil Burk9dca9822017-05-26 14:27:43 -070063aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
Phil Burk5ed503c2017-02-01 09:38:15 -080064
Phil Burkd4ccc622017-12-20 15:32:44 -080065
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
72audio_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 */
79audio_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 */
86audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
87
Kevin Rocard68646ba2019-03-20 13:26:49 -070088/**
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 */
93audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
94 aaudio_allowed_capture_policy_t policy);
95
Eric Laurentd17c8502019-10-24 15:58:35 -070096audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
97 bool privacySensitive);
98
jiabina9094092021-06-28 20:36:45 +000099audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelLayoutMask(
100 aaudio_channel_mask_t channelMask, bool isInput);
101
102aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelLayoutMask(
103 audio_channel_mask_t channelMask, bool isInput);
104
105aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelIndexMask(
106 audio_channel_mask_t channelMask);
107
108audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelIndexMask(
109 aaudio_channel_mask_t channelMask);
110
111aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelMask(
112 audio_channel_mask_t channelMask, bool isInput, bool indexMaskRequired);
113
114audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelMask(
115 aaudio_channel_mask_t channelMask, bool isInput);
116
117bool AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask);
118
119int32_t AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask);
120
121aaudio_channel_mask_t AAudioConvert_channelCountToMask(int32_t channelCount);
122
123audio_channel_mask_t AAudio_getChannelMaskForOpen(
124 aaudio_channel_mask_t channelMask, int32_t samplesPerFrame, bool isInput);
125
Phil Burkc8f69a02017-05-11 15:53:06 -0700126// Note that this code may be replaced by Settings or by some other system configuration tool.
127
Phil Burkb31b66f2019-09-30 09:33:41 -0700128/**
129 * Read system property.
130 * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
131 */
132int32_t AAudioProperty_getMMapPolicy();
Phil Burkd04aeea2017-05-23 13:56:41 -0700133#define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy"
Phil Burkc8f69a02017-05-11 15:53:06 -0700134
135/**
136 * Read system property.
Phil Burkd04aeea2017-05-23 13:56:41 -0700137 * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
Phil Burkc8f69a02017-05-11 15:53:06 -0700138 */
Phil Burkd04aeea2017-05-23 13:56:41 -0700139int32_t AAudioProperty_getMMapExclusivePolicy();
Phil Burkb31b66f2019-09-30 09:33:41 -0700140#define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy"
Phil Burkc8f69a02017-05-11 15:53:06 -0700141
142/**
143 * Read system property.
Phil Burkfd34a932017-07-19 07:03:52 -0700144 * @return number of bursts per AAudio service mixer cycle
Phil Burkc8f69a02017-05-11 15:53:06 -0700145 */
146int32_t AAudioProperty_getMixerBursts();
Phil Burkb31b66f2019-09-30 09:33:41 -0700147#define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts"
Phil Burkc8f69a02017-05-11 15:53:06 -0700148
149/**
Phil Burkfd34a932017-07-19 07:03:52 -0700150 * Read a system property that specifies the number of extra microseconds that a thread
151 * should sleep when waiting for another thread to service a FIFO. This is used
152 * to avoid the waking thread from being overly optimistic about the other threads
153 * wakeup timing. This value should be set high enough to cover typical scheduling jitter
154 * for a real-time thread.
155 *
156 * @return number of microseconds to delay the wakeup.
157 */
158int32_t AAudioProperty_getWakeupDelayMicros();
Phil Burkfd34a932017-07-19 07:03:52 -0700159#define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec"
160
161/**
162 * Read a system property that specifies the minimum sleep time when polling the FIFO.
163 *
164 * @return minimum number of microseconds to sleep.
165 */
166int32_t AAudioProperty_getMinimumSleepMicros();
Phil Burkfd34a932017-07-19 07:03:52 -0700167#define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec"
168
169/**
Phil Burkc8f69a02017-05-11 15:53:06 -0700170 * Read system property.
171 * This is handy in case the DMA is bursting too quickly for the CPU to keep up.
172 * For example, there may be a DMA burst every 100 usec but you only
173 * want to feed the MMAP buffer every 2000 usec.
174 *
175 * This will affect the framesPerBurst for an MMAP stream.
176 *
177 * @return minimum number of microseconds for a MMAP HW burst
178 */
179int32_t AAudioProperty_getHardwareBurstMinMicros();
Phil Burkb31b66f2019-09-30 09:33:41 -0700180#define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec"
Phil Burkc8f69a02017-05-11 15:53:06 -0700181
Phil Burkb31b66f2019-09-30 09:33:41 -0700182/**
183 * Read a system property that specifies an offset that will be added to MMAP timestamps.
184 * This can be used to correct bias in the timestamp.
185 * It can also be used to analyze the time distribution of the timestamp
186 * by progressively modifying the offset and listening for glitches.
187 *
188 * @return number of microseconds to offset the time part of an MMAP timestamp
189 */
190int32_t AAudioProperty_getInputMMapOffsetMicros();
191#define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC "aaudio.in_mmap_offset_usec"
192
193int32_t AAudioProperty_getOutputMMapOffsetMicros();
194#define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC "aaudio.out_mmap_offset_usec"
Phil Burk5cc83c32017-11-28 15:43:18 -0800195
Phil Burkef34be52019-09-26 13:45:25 -0700196// These are powers of two that can be combined as a bit mask.
197// AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM must be enabled before the stream is opened.
198#define AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM 1
199#define AAUDIO_LOG_RESERVED_2 2
200#define AAUDIO_LOG_RESERVED_4 4
201#define AAUDIO_LOG_RESERVED_8 8
202
203/**
204 * Use a mask to enable various logs in AAudio.
205 * @return mask that enables various AAudio logs, such as AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM
206 */
207int32_t AAudioProperty_getLogMask();
208#define AAUDIO_PROP_LOG_MASK "aaudio.log_mask"
209
Phil Burk5cc83c32017-11-28 15:43:18 -0800210/**
211 * Is flush allowed for the given state?
212 * @param state
213 * @return AAUDIO_OK if allowed or an error
214 */
215aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state);
216
Andy Hung47c5e532017-06-26 18:28:00 -0700217/**
218 * Try a function f until it returns true.
219 *
220 * The function is always called at least once.
221 *
222 * @param f the function to evaluate, which returns a bool.
223 * @param times the number of times to evaluate f.
224 * @param sleepMs the sleep time per check of f, if greater than 0.
225 * @return true if f() eventually returns true.
226 */
227static inline bool AAudio_tryUntilTrue(
228 std::function<bool()> f, int times, int sleepMs) {
229 static const useconds_t US_PER_MS = 1000;
230
231 sleepMs = std::max(sleepMs, 0);
232 for (;;) {
233 if (f()) return true;
234 if (times <= 1) return false;
235 --times;
236 usleep(sleepMs * US_PER_MS);
237 }
238}
239
Phil Burk97350f92017-07-21 15:59:44 -0700240
241/**
242 * Simple double buffer for a structure that can be written occasionally and read occasionally.
243 * This allows a SINGLE writer with multiple readers.
244 *
245 * It is OK if the FIFO overflows and we lose old values.
246 * It is also OK if we read an old value.
247 * Thread may return a non-atomic result if the other thread is rapidly writing
248 * new values on another core.
249 */
250template <class T>
251class SimpleDoubleBuffer {
252public:
253 SimpleDoubleBuffer()
Phil Burkbcc36742017-08-31 17:24:51 -0700254 : mValues() {}
Phil Burk97350f92017-07-21 15:59:44 -0700255
256 __attribute__((no_sanitize("integer")))
257 void write(T value) {
258 int index = mCounter.load() & 1;
259 mValues[index] = value;
260 mCounter++; // Increment AFTER updating storage, OK if it wraps.
261 }
262
Phil Burkbcc36742017-08-31 17:24:51 -0700263 /**
264 * This should only be called by the same thread that calls write() or when
265 * no other thread is calling write.
266 */
267 void clear() {
268 mCounter.store(0);
269 }
270
Phil Burk97350f92017-07-21 15:59:44 -0700271 T read() const {
272 T result;
273 int before;
274 int after;
275 int timeout = 3;
276 do {
277 // Check to see if a write occurred while were reading.
278 before = mCounter.load();
279 int index = (before & 1) ^ 1;
280 result = mValues[index];
281 after = mCounter.load();
Phil Burkbcc36742017-08-31 17:24:51 -0700282 } while ((after != before) && (after > 0) && (--timeout > 0));
Phil Burk97350f92017-07-21 15:59:44 -0700283 return result;
284 }
285
286 /**
287 * @return true if at least one value has been written
288 */
289 bool isValid() const {
290 return mCounter.load() > 0;
291 }
292
293private:
294 T mValues[2];
Phil Burkbcc36742017-08-31 17:24:51 -0700295 std::atomic<int> mCounter{0};
Phil Burk97350f92017-07-21 15:59:44 -0700296};
297
298class Timestamp {
299public:
300 Timestamp()
301 : mPosition(0)
302 , mNanoseconds(0) {}
303 Timestamp(int64_t position, int64_t nanoseconds)
304 : mPosition(position)
305 , mNanoseconds(nanoseconds) {}
306
307 int64_t getPosition() const { return mPosition; }
308
309 int64_t getNanoseconds() const { return mNanoseconds; }
310
311private:
312 // These cannot be const because we need to implement the copy assignment operator.
313 int64_t mPosition;
314 int64_t mNanoseconds;
315};
316
Phil Burkbcc36742017-08-31 17:24:51 -0700317
318/**
319 * Pass a request to another thread.
320 * This is used when one thread, A, wants another thread, B, to do something.
321 * A naive approach would be for A to set a flag and for B to clear it when done.
322 * But that creates a race condition. This technique avoids the race condition.
323 *
324 * Assumes only one requester and one acknowledger.
325 */
326class AtomicRequestor {
327public:
Phil Burk2d5ba532017-09-06 14:36:11 -0700328
329 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700330 void request() {
Phil Burkbcc36742017-08-31 17:24:51 -0700331 mRequested++;
332 }
333
Phil Burk2d5ba532017-09-06 14:36:11 -0700334 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700335 bool isRequested() {
Phil Burk2d5ba532017-09-06 14:36:11 -0700336 return (mRequested.load() - mAcknowledged.load()) > 0;
Phil Burkbcc36742017-08-31 17:24:51 -0700337 }
338
Phil Burk2d5ba532017-09-06 14:36:11 -0700339 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700340 void acknowledge() {
341 mAcknowledged++;
342 }
343
344private:
345 std::atomic<int> mRequested{0};
346 std::atomic<int> mAcknowledged{0};
347};
jiabina9094092021-06-28 20:36:45 +0000348
349enum {
350 /**
351 * Audio channel index mask, only used internally.
352 */
353 AAUDIO_CHANNEL_BIT_INDEX = 0x80000000,
354 AAUDIO_CHANNEL_INDEX_MASK_1 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 1) - 1,
355 AAUDIO_CHANNEL_INDEX_MASK_2 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 2) - 1,
356 AAUDIO_CHANNEL_INDEX_MASK_3 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 3) - 1,
357 AAUDIO_CHANNEL_INDEX_MASK_4 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 4) - 1,
358 AAUDIO_CHANNEL_INDEX_MASK_5 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 5) - 1,
359 AAUDIO_CHANNEL_INDEX_MASK_6 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 6) - 1,
360 AAUDIO_CHANNEL_INDEX_MASK_7 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 7) - 1,
361 AAUDIO_CHANNEL_INDEX_MASK_8 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 8) - 1,
362 AAUDIO_CHANNEL_INDEX_MASK_9 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 9) - 1,
363 AAUDIO_CHANNEL_INDEX_MASK_10 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 10) - 1,
364 AAUDIO_CHANNEL_INDEX_MASK_11 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 11) - 1,
365 AAUDIO_CHANNEL_INDEX_MASK_12 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 12) - 1,
366 AAUDIO_CHANNEL_INDEX_MASK_13 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 13) - 1,
367 AAUDIO_CHANNEL_INDEX_MASK_14 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 14) - 1,
368 AAUDIO_CHANNEL_INDEX_MASK_15 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 15) - 1,
369 AAUDIO_CHANNEL_INDEX_MASK_16 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 16) - 1,
370 AAUDIO_CHANNEL_INDEX_MASK_17 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 17) - 1,
371 AAUDIO_CHANNEL_INDEX_MASK_18 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 18) - 1,
372 AAUDIO_CHANNEL_INDEX_MASK_19 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 19) - 1,
373 AAUDIO_CHANNEL_INDEX_MASK_20 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 20) - 1,
374 AAUDIO_CHANNEL_INDEX_MASK_21 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 21) - 1,
375 AAUDIO_CHANNEL_INDEX_MASK_22 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 22) - 1,
376 AAUDIO_CHANNEL_INDEX_MASK_23 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 23) - 1,
377 AAUDIO_CHANNEL_INDEX_MASK_24 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 24) - 1,
378};
379
Phil Burk5ed503c2017-02-01 09:38:15 -0800380#endif //UTILITY_AAUDIO_UTILITIES_H