blob: dc2b198d8e26eb66e3672ac324403438ef42c7b6 [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>
24
25#include <utils/Errors.h>
Kevin Rocard6d7582e2018-01-11 19:28:14 -080026#include <system/audio.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080027
Phil Burka4eb0d82017-04-12 15:44:06 -070028#include "aaudio/AAudio.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080029
30/**
31 * Convert an AAudio result into the closest matching Android status.
32 */
33android::status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result);
34
35/**
36 * Convert an Android status into the closest matching AAudio result.
37 */
38aaudio_result_t AAudioConvert_androidToAAudioResult(android::status_t status);
39
Phil Burke572f462017-04-20 13:03:19 -070040/**
Phil Burk4e1af9f2018-01-03 15:54:35 -080041 * Convert an aaudio_session_id_t to a value that is safe to pass to AudioFlinger.
42 * @param sessionId
43 * @return safe value
44 */
45audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
46
47/**
Phil Burk5ed503c2017-02-01 09:38:15 -080048 * Calculate the number of bytes and prevent numeric overflow.
Phil Burk7f680132018-03-12 14:48:06 -070049 * The *sizeInBytes will be set to zero if there is an error.
50 *
Phil Burk5ed503c2017-02-01 09:38:15 -080051 * @param numFrames frame count
52 * @param bytesPerFrame size of a frame in bytes
Phil Burk7f680132018-03-12 14:48:06 -070053 * @param sizeInBytes pointer to a variable to receive total size in bytes
Phil Burk5ed503c2017-02-01 09:38:15 -080054 * @return AAUDIO_OK or negative error, eg. AAUDIO_ERROR_OUT_OF_RANGE
55 */
Phil Burk3316d5e2017-02-15 11:23:01 -080056int32_t AAudioConvert_framesToBytes(int32_t numFrames,
Phil Burk7f680132018-03-12 14:48:06 -070057 int32_t bytesPerFrame,
58 int32_t *sizeInBytes);
Phil Burk5ed503c2017-02-01 09:38:15 -080059
Phil Burk9dca9822017-05-26 14:27:43 -070060audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudio_format);
Phil Burk5ed503c2017-02-01 09:38:15 -080061
Phil Burk9dca9822017-05-26 14:27:43 -070062aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
Phil Burk5ed503c2017-02-01 09:38:15 -080063
Phil Burkd4ccc622017-12-20 15:32:44 -080064
65/**
66 * Note that this function does not validate the passed in value.
67 * That is done somewhere else.
68 * @return internal value
69 */
70
71audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage);
72
73/**
74 * Note that this function does not validate the passed in value.
75 * That is done somewhere else.
76 * @return internal value
77 */
78audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType);
79
80/**
81 * Note that this function does not validate the passed in value.
82 * That is done somewhere else.
83 * @return internal audio source
84 */
85audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
86
Phil Burkc8f69a02017-05-11 15:53:06 -070087// Note that this code may be replaced by Settings or by some other system configuration tool.
88
Phil Burkd04aeea2017-05-23 13:56:41 -070089#define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy"
Phil Burkc8f69a02017-05-11 15:53:06 -070090
91/**
92 * Read system property.
Phil Burkd04aeea2017-05-23 13:56:41 -070093 * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
Phil Burkc8f69a02017-05-11 15:53:06 -070094 */
Phil Burkd04aeea2017-05-23 13:56:41 -070095int32_t AAudioProperty_getMMapPolicy();
Phil Burkc8f69a02017-05-11 15:53:06 -070096
Phil Burkd04aeea2017-05-23 13:56:41 -070097#define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy"
Phil Burkc8f69a02017-05-11 15:53:06 -070098
99/**
100 * Read system property.
Phil Burkd04aeea2017-05-23 13:56:41 -0700101 * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
Phil Burkc8f69a02017-05-11 15:53:06 -0700102 */
Phil Burkd04aeea2017-05-23 13:56:41 -0700103int32_t AAudioProperty_getMMapExclusivePolicy();
Phil Burkc8f69a02017-05-11 15:53:06 -0700104
105#define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts"
106
107/**
108 * Read system property.
Phil Burkfd34a932017-07-19 07:03:52 -0700109 * @return number of bursts per AAudio service mixer cycle
Phil Burkc8f69a02017-05-11 15:53:06 -0700110 */
111int32_t AAudioProperty_getMixerBursts();
112
113#define AAUDIO_PROP_HW_BURST_MIN_USEC "aaudio.hw_burst_min_usec"
114
115/**
Phil Burkfd34a932017-07-19 07:03:52 -0700116 * Read a system property that specifies the number of extra microseconds that a thread
117 * should sleep when waiting for another thread to service a FIFO. This is used
118 * to avoid the waking thread from being overly optimistic about the other threads
119 * wakeup timing. This value should be set high enough to cover typical scheduling jitter
120 * for a real-time thread.
121 *
122 * @return number of microseconds to delay the wakeup.
123 */
124int32_t AAudioProperty_getWakeupDelayMicros();
125
126#define AAUDIO_PROP_WAKEUP_DELAY_USEC "aaudio.wakeup_delay_usec"
127
128/**
129 * Read a system property that specifies the minimum sleep time when polling the FIFO.
130 *
131 * @return minimum number of microseconds to sleep.
132 */
133int32_t AAudioProperty_getMinimumSleepMicros();
134
135#define AAUDIO_PROP_MINIMUM_SLEEP_USEC "aaudio.minimum_sleep_usec"
136
137/**
Phil Burkc8f69a02017-05-11 15:53:06 -0700138 * Read system property.
139 * This is handy in case the DMA is bursting too quickly for the CPU to keep up.
140 * For example, there may be a DMA burst every 100 usec but you only
141 * want to feed the MMAP buffer every 2000 usec.
142 *
143 * This will affect the framesPerBurst for an MMAP stream.
144 *
145 * @return minimum number of microseconds for a MMAP HW burst
146 */
147int32_t AAudioProperty_getHardwareBurstMinMicros();
148
Phil Burk5cc83c32017-11-28 15:43:18 -0800149
150/**
151 * Is flush allowed for the given state?
152 * @param state
153 * @return AAUDIO_OK if allowed or an error
154 */
155aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state);
156
Andy Hung47c5e532017-06-26 18:28:00 -0700157/**
158 * Try a function f until it returns true.
159 *
160 * The function is always called at least once.
161 *
162 * @param f the function to evaluate, which returns a bool.
163 * @param times the number of times to evaluate f.
164 * @param sleepMs the sleep time per check of f, if greater than 0.
165 * @return true if f() eventually returns true.
166 */
167static inline bool AAudio_tryUntilTrue(
168 std::function<bool()> f, int times, int sleepMs) {
169 static const useconds_t US_PER_MS = 1000;
170
171 sleepMs = std::max(sleepMs, 0);
172 for (;;) {
173 if (f()) return true;
174 if (times <= 1) return false;
175 --times;
176 usleep(sleepMs * US_PER_MS);
177 }
178}
179
Phil Burk97350f92017-07-21 15:59:44 -0700180
181/**
182 * Simple double buffer for a structure that can be written occasionally and read occasionally.
183 * This allows a SINGLE writer with multiple readers.
184 *
185 * It is OK if the FIFO overflows and we lose old values.
186 * It is also OK if we read an old value.
187 * Thread may return a non-atomic result if the other thread is rapidly writing
188 * new values on another core.
189 */
190template <class T>
191class SimpleDoubleBuffer {
192public:
193 SimpleDoubleBuffer()
Phil Burkbcc36742017-08-31 17:24:51 -0700194 : mValues() {}
Phil Burk97350f92017-07-21 15:59:44 -0700195
196 __attribute__((no_sanitize("integer")))
197 void write(T value) {
198 int index = mCounter.load() & 1;
199 mValues[index] = value;
200 mCounter++; // Increment AFTER updating storage, OK if it wraps.
201 }
202
Phil Burkbcc36742017-08-31 17:24:51 -0700203 /**
204 * This should only be called by the same thread that calls write() or when
205 * no other thread is calling write.
206 */
207 void clear() {
208 mCounter.store(0);
209 }
210
Phil Burk97350f92017-07-21 15:59:44 -0700211 T read() const {
212 T result;
213 int before;
214 int after;
215 int timeout = 3;
216 do {
217 // Check to see if a write occurred while were reading.
218 before = mCounter.load();
219 int index = (before & 1) ^ 1;
220 result = mValues[index];
221 after = mCounter.load();
Phil Burkbcc36742017-08-31 17:24:51 -0700222 } while ((after != before) && (after > 0) && (--timeout > 0));
Phil Burk97350f92017-07-21 15:59:44 -0700223 return result;
224 }
225
226 /**
227 * @return true if at least one value has been written
228 */
229 bool isValid() const {
230 return mCounter.load() > 0;
231 }
232
233private:
234 T mValues[2];
Phil Burkbcc36742017-08-31 17:24:51 -0700235 std::atomic<int> mCounter{0};
Phil Burk97350f92017-07-21 15:59:44 -0700236};
237
238class Timestamp {
239public:
240 Timestamp()
241 : mPosition(0)
242 , mNanoseconds(0) {}
243 Timestamp(int64_t position, int64_t nanoseconds)
244 : mPosition(position)
245 , mNanoseconds(nanoseconds) {}
246
247 int64_t getPosition() const { return mPosition; }
248
249 int64_t getNanoseconds() const { return mNanoseconds; }
250
251private:
252 // These cannot be const because we need to implement the copy assignment operator.
253 int64_t mPosition;
254 int64_t mNanoseconds;
255};
256
Phil Burkbcc36742017-08-31 17:24:51 -0700257
258/**
259 * Pass a request to another thread.
260 * This is used when one thread, A, wants another thread, B, to do something.
261 * A naive approach would be for A to set a flag and for B to clear it when done.
262 * But that creates a race condition. This technique avoids the race condition.
263 *
264 * Assumes only one requester and one acknowledger.
265 */
266class AtomicRequestor {
267public:
Phil Burk2d5ba532017-09-06 14:36:11 -0700268
269 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700270 void request() {
Phil Burkbcc36742017-08-31 17:24:51 -0700271 mRequested++;
272 }
273
Phil Burk2d5ba532017-09-06 14:36:11 -0700274 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700275 bool isRequested() {
Phil Burk2d5ba532017-09-06 14:36:11 -0700276 return (mRequested.load() - mAcknowledged.load()) > 0;
Phil Burkbcc36742017-08-31 17:24:51 -0700277 }
278
Phil Burk2d5ba532017-09-06 14:36:11 -0700279 __attribute__((no_sanitize("integer")))
Phil Burkbcc36742017-08-31 17:24:51 -0700280 void acknowledge() {
281 mAcknowledged++;
282 }
283
284private:
285 std::atomic<int> mRequested{0};
286 std::atomic<int> mAcknowledged{0};
287};
Phil Burk5ed503c2017-02-01 09:38:15 -0800288#endif //UTILITY_AAUDIO_UTILITIES_H