blob: ac75306497b6d987d88a31b9a1f45fd717b724e7 [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>
jiabin4a341862022-09-20 17:58:37 +000022#include <vector>
Phil Burk5ed503c2017-02-01 09:38:15 -080023#include <stdint.h>
24#include <sys/types.h>
Tom Cherry7ae78252020-04-13 15:20:50 -070025#include <unistd.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080026
jiabin4a341862022-09-20 17:58:37 +000027#include <android/media/audio/common/AudioMMapPolicyInfo.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080028#include <utils/Errors.h>
Kevin Rocard6d7582e2018-01-11 19:28:14 -080029#include <system/audio.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080030
Phil Burka4eb0d82017-04-12 15:44:06 -070031#include "aaudio/AAudio.h"
jiabin4a341862022-09-20 17:58:37 +000032#include "aaudio/AAudioTesting.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080033
34/**
35 * Convert an AAudio result into the closest matching Android status.
36 */
37android::status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result);
38
39/**
40 * Convert an Android status into the closest matching AAudio result.
41 */
42aaudio_result_t AAudioConvert_androidToAAudioResult(android::status_t status);
43
Phil Burke572f462017-04-20 13:03:19 -070044/**
Phil Burk4e1af9f2018-01-03 15:54:35 -080045 * Convert an aaudio_session_id_t to a value that is safe to pass to AudioFlinger.
46 * @param sessionId
47 * @return safe value
48 */
49audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
50
51/**
Phil Burk5ed503c2017-02-01 09:38:15 -080052 * Calculate the number of bytes and prevent numeric overflow.
Phil Burk7f680132018-03-12 14:48:06 -070053 * The *sizeInBytes will be set to zero if there is an error.
54 *
Phil Burk5ed503c2017-02-01 09:38:15 -080055 * @param numFrames frame count
56 * @param bytesPerFrame size of a frame in bytes
Phil Burk7f680132018-03-12 14:48:06 -070057 * @param sizeInBytes pointer to a variable to receive total size in bytes
Phil Burk5ed503c2017-02-01 09:38:15 -080058 * @return AAUDIO_OK or negative error, eg. AAUDIO_ERROR_OUT_OF_RANGE
59 */
Phil Burk3316d5e2017-02-15 11:23:01 -080060int32_t AAudioConvert_framesToBytes(int32_t numFrames,
Phil Burk7f680132018-03-12 14:48:06 -070061 int32_t bytesPerFrame,
62 int32_t *sizeInBytes);
Phil Burk5ed503c2017-02-01 09:38:15 -080063
Phil Burk9dca9822017-05-26 14:27:43 -070064audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudio_format);
Phil Burk5ed503c2017-02-01 09:38:15 -080065
Phil Burk9dca9822017-05-26 14:27:43 -070066aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
Phil Burk5ed503c2017-02-01 09:38:15 -080067
Phil Burkd4ccc622017-12-20 15:32:44 -080068
69/**
70 * Note that this function does not validate the passed in value.
71 * That is done somewhere else.
72 * @return internal value
73 */
74
75audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage);
76
77/**
78 * Note that this function does not validate the passed in value.
79 * That is done somewhere else.
80 * @return internal value
81 */
82audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType);
83
84/**
85 * Note that this function does not validate the passed in value.
86 * That is done somewhere else.
87 * @return internal audio source
88 */
89audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
90
Kevin Rocard68646ba2019-03-20 13:26:49 -070091/**
92 * Note that this function does not validate the passed in value.
93 * That is done somewhere else.
94 * @return internal audio flags mask
95 */
96audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
Jean-Michel Trivi656bfdc2021-09-20 18:42:37 -070097 aaudio_allowed_capture_policy_t policy,
98 aaudio_spatialization_behavior_t spatializationBehavior,
99 bool isContentSpatialized);
Kevin Rocard68646ba2019-03-20 13:26:49 -0700100
Eric Laurentd17c8502019-10-24 15:58:35 -0700101audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
102 bool privacySensitive);
103
jiabina9094092021-06-28 20:36:45 +0000104audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelLayoutMask(
105 aaudio_channel_mask_t channelMask, bool isInput);
106
107aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelLayoutMask(
108 audio_channel_mask_t channelMask, bool isInput);
109
110aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelIndexMask(
111 audio_channel_mask_t channelMask);
112
113audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelIndexMask(
114 aaudio_channel_mask_t channelMask);
115
116aaudio_channel_mask_t AAudioConvert_androidToAAudioChannelMask(
117 audio_channel_mask_t channelMask, bool isInput, bool indexMaskRequired);
118
119audio_channel_mask_t AAudioConvert_aaudioToAndroidChannelMask(
120 aaudio_channel_mask_t channelMask, bool isInput);
121
122bool AAudio_isChannelIndexMask(aaudio_channel_mask_t channelMask);
123
124int32_t AAudioConvert_channelMaskToCount(aaudio_channel_mask_t channelMask);
125
126aaudio_channel_mask_t AAudioConvert_channelCountToMask(int32_t channelCount);
127
128audio_channel_mask_t AAudio_getChannelMaskForOpen(
129 aaudio_channel_mask_t channelMask, int32_t samplesPerFrame, bool isInput);
130
Phil Burkc8f69a02017-05-11 15:53:06 -0700131// Note that this code may be replaced by Settings or by some other system configuration tool.
132
Phil Burkb31b66f2019-09-30 09:33:41 -0700133/**
Phil Burkfd34a932017-07-19 07:03:52 -0700134 * Read a system property that specifies the number of extra microseconds that a thread
135 * should sleep when waiting for another thread to service a FIFO. This is used
136 * to avoid the waking thread from being overly optimistic about the other threads
137 * wakeup timing. This value should be set high enough to cover typical scheduling jitter
138 * for a real-time thread.
139 *
140 * @return number of microseconds to delay the wakeup.
141 */
142int32_t AAudioProperty_getWakeupDelayMicros();
Phil Burkfd34a932017-07-19 07:03:52 -0700143#define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec"
144
145/**
146 * Read a system property that specifies the minimum sleep time when polling the FIFO.
147 *
148 * @return minimum number of microseconds to sleep.
149 */
150int32_t AAudioProperty_getMinimumSleepMicros();
Phil Burkfd34a932017-07-19 07:03:52 -0700151#define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec"
152
153/**
Phil Burkb31b66f2019-09-30 09:33:41 -0700154 * Read a system property that specifies an offset that will be added to MMAP timestamps.
155 * This can be used to correct bias in the timestamp.
156 * It can also be used to analyze the time distribution of the timestamp
157 * by progressively modifying the offset and listening for glitches.
158 *
159 * @return number of microseconds to offset the time part of an MMAP timestamp
160 */
161int32_t AAudioProperty_getInputMMapOffsetMicros();
162#define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC "aaudio.in_mmap_offset_usec"
163
164int32_t AAudioProperty_getOutputMMapOffsetMicros();
165#define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC "aaudio.out_mmap_offset_usec"
Phil Burk5cc83c32017-11-28 15:43:18 -0800166
Phil Burkef34be52019-09-26 13:45:25 -0700167// These are powers of two that can be combined as a bit mask.
168// AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM must be enabled before the stream is opened.
169#define AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM 1
170#define AAUDIO_LOG_RESERVED_2 2
171#define AAUDIO_LOG_RESERVED_4 4
172#define AAUDIO_LOG_RESERVED_8 8
173
174/**
175 * Use a mask to enable various logs in AAudio.
176 * @return mask that enables various AAudio logs, such as AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM
177 */
178int32_t AAudioProperty_getLogMask();
179#define AAUDIO_PROP_LOG_MASK "aaudio.log_mask"
180
Phil Burk5cc83c32017-11-28 15:43:18 -0800181/**
182 * Is flush allowed for the given state?
183 * @param state
184 * @return AAUDIO_OK if allowed or an error
185 */
186aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state);
187
Andy Hung47c5e532017-06-26 18:28:00 -0700188/**
189 * Try a function f until it returns true.
190 *
191 * The function is always called at least once.
192 *
193 * @param f the function to evaluate, which returns a bool.
194 * @param times the number of times to evaluate f.
195 * @param sleepMs the sleep time per check of f, if greater than 0.
196 * @return true if f() eventually returns true.
197 */
198static inline bool AAudio_tryUntilTrue(
jiabind5bd06a2021-04-27 22:04:08 +0000199 const std::function<bool()>& f, int times, int sleepMs) {
Andy Hung47c5e532017-06-26 18:28:00 -0700200 static const useconds_t US_PER_MS = 1000;
201
202 sleepMs = std::max(sleepMs, 0);
203 for (;;) {
204 if (f()) return true;
205 if (times <= 1) return false;
206 --times;
207 usleep(sleepMs * US_PER_MS);
208 }
209}
210
Phil Burk97350f92017-07-21 15:59:44 -0700211
212/**
213 * Simple double buffer for a structure that can be written occasionally and read occasionally.
214 * This allows a SINGLE writer with multiple readers.
215 *
216 * It is OK if the FIFO overflows and we lose old values.
217 * It is also OK if we read an old value.
218 * Thread may return a non-atomic result if the other thread is rapidly writing
219 * new values on another core.
220 */
221template <class T>
222class SimpleDoubleBuffer {
223public:
224 SimpleDoubleBuffer()
Phil Burkbcc36742017-08-31 17:24:51 -0700225 : mValues() {}
Phil Burk97350f92017-07-21 15:59:44 -0700226
227 __attribute__((no_sanitize("integer")))
228 void write(T value) {
229 int index = mCounter.load() & 1;
230 mValues[index] = value;
231 mCounter++; // Increment AFTER updating storage, OK if it wraps.
232 }
233
Phil Burkbcc36742017-08-31 17:24:51 -0700234 /**
235 * This should only be called by the same thread that calls write() or when
236 * no other thread is calling write.
237 */
238 void clear() {
239 mCounter.store(0);
240 }
241
Phil Burk97350f92017-07-21 15:59:44 -0700242 T read() const {
243 T result;
244 int before;
245 int after;
246 int timeout = 3;
247 do {
248 // Check to see if a write occurred while were reading.
249 before = mCounter.load();
250 int index = (before & 1) ^ 1;
251 result = mValues[index];
252 after = mCounter.load();
Phil Burkbcc36742017-08-31 17:24:51 -0700253 } while ((after != before) && (after > 0) && (--timeout > 0));
Phil Burk97350f92017-07-21 15:59:44 -0700254 return result;
255 }
256
257 /**
258 * @return true if at least one value has been written
259 */
260 bool isValid() const {
261 return mCounter.load() > 0;
262 }
263
264private:
265 T mValues[2];
Phil Burkbcc36742017-08-31 17:24:51 -0700266 std::atomic<int> mCounter{0};
Phil Burk97350f92017-07-21 15:59:44 -0700267};
268
269class Timestamp {
270public:
jiabind5bd06a2021-04-27 22:04:08 +0000271 Timestamp() = default;
Phil Burk97350f92017-07-21 15:59:44 -0700272 Timestamp(int64_t position, int64_t nanoseconds)
273 : mPosition(position)
274 , mNanoseconds(nanoseconds) {}
275
276 int64_t getPosition() const { return mPosition; }
277
278 int64_t getNanoseconds() const { return mNanoseconds; }
279
280private:
281 // These cannot be const because we need to implement the copy assignment operator.
jiabind5bd06a2021-04-27 22:04:08 +0000282 int64_t mPosition{0};
283 int64_t mNanoseconds{0};
Phil Burk97350f92017-07-21 15:59:44 -0700284};
285
Phil Burkbcc36742017-08-31 17:24:51 -0700286
287/**
288 * Pass a request to another thread.
289 * This is used when one thread, A, wants another thread, B, to do something.
290 * A naive approach would be for A to set a flag and for B to clear it when done.
291 * But that creates a race condition. This technique avoids the race condition.
292 *
293 * Assumes only one requester and one acknowledger.
294 */
295class AtomicRequestor {
296public:
Phil Burk2d5ba532017-09-06 14:36:11 -0700297
298 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700299 void request() {
Phil Burkbcc36742017-08-31 17:24:51 -0700300 mRequested++;
301 }
302
Phil Burk2d5ba532017-09-06 14:36:11 -0700303 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700304 bool isRequested() {
Phil Burk2d5ba532017-09-06 14:36:11 -0700305 return (mRequested.load() - mAcknowledged.load()) > 0;
Phil Burkbcc36742017-08-31 17:24:51 -0700306 }
307
Phil Burk2d5ba532017-09-06 14:36:11 -0700308 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700309 void acknowledge() {
310 mAcknowledged++;
311 }
312
313private:
314 std::atomic<int> mRequested{0};
315 std::atomic<int> mAcknowledged{0};
316};
jiabina9094092021-06-28 20:36:45 +0000317
318enum {
319 /**
320 * Audio channel index mask, only used internally.
321 */
322 AAUDIO_CHANNEL_BIT_INDEX = 0x80000000,
323 AAUDIO_CHANNEL_INDEX_MASK_1 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 1) - 1,
324 AAUDIO_CHANNEL_INDEX_MASK_2 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 2) - 1,
325 AAUDIO_CHANNEL_INDEX_MASK_3 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 3) - 1,
326 AAUDIO_CHANNEL_INDEX_MASK_4 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 4) - 1,
327 AAUDIO_CHANNEL_INDEX_MASK_5 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 5) - 1,
328 AAUDIO_CHANNEL_INDEX_MASK_6 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 6) - 1,
329 AAUDIO_CHANNEL_INDEX_MASK_7 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 7) - 1,
330 AAUDIO_CHANNEL_INDEX_MASK_8 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 8) - 1,
331 AAUDIO_CHANNEL_INDEX_MASK_9 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 9) - 1,
332 AAUDIO_CHANNEL_INDEX_MASK_10 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 10) - 1,
333 AAUDIO_CHANNEL_INDEX_MASK_11 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 11) - 1,
334 AAUDIO_CHANNEL_INDEX_MASK_12 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 12) - 1,
335 AAUDIO_CHANNEL_INDEX_MASK_13 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 13) - 1,
336 AAUDIO_CHANNEL_INDEX_MASK_14 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 14) - 1,
337 AAUDIO_CHANNEL_INDEX_MASK_15 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 15) - 1,
338 AAUDIO_CHANNEL_INDEX_MASK_16 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 16) - 1,
339 AAUDIO_CHANNEL_INDEX_MASK_17 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 17) - 1,
340 AAUDIO_CHANNEL_INDEX_MASK_18 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 18) - 1,
341 AAUDIO_CHANNEL_INDEX_MASK_19 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 19) - 1,
342 AAUDIO_CHANNEL_INDEX_MASK_20 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 20) - 1,
343 AAUDIO_CHANNEL_INDEX_MASK_21 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 21) - 1,
344 AAUDIO_CHANNEL_INDEX_MASK_22 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 22) - 1,
345 AAUDIO_CHANNEL_INDEX_MASK_23 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 23) - 1,
346 AAUDIO_CHANNEL_INDEX_MASK_24 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 24) - 1,
347};
348
jiabin4a341862022-09-20 17:58:37 +0000349// The aaudio policy will be ALWAYS, NEVER, UNSPECIFIED only when all policy info are
350// ALWAYS, NEVER or UNSPECIFIED. Otherwise, the aaudio policy will be AUTO.
351aaudio_policy_t AAudio_getAAudioPolicy(
352 const std::vector<android::media::audio::common::AudioMMapPolicyInfo>& policyInfos);
353
Phil Burk5ed503c2017-02-01 09:38:15 -0800354#endif //UTILITY_AAUDIO_UTILITIES_H