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 system property.
132  * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
133  */
134 int32_t AAudioProperty_getMMapPolicy();
135 #define AAUDIO_PROP_MMAP_POLICY           "aaudio.mmap_policy"
136 
137 /**
138  * Read system property.
139  * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
140  */
141 int32_t AAudioProperty_getMMapExclusivePolicy();
142 #define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy"
143 
144 /**
145  * Read system property.
146  * @return number of bursts per AAudio service mixer cycle
147  */
148 int32_t AAudioProperty_getMixerBursts();
149 #define AAUDIO_PROP_MIXER_BURSTS           "aaudio.mixer_bursts"
150 
151 /**
152  * Read a system property that specifies the number of extra microseconds that a thread
153  * should sleep when waiting for another thread to service a FIFO. This is used
154  * to avoid the waking thread from being overly optimistic about the other threads
155  * wakeup timing. This value should be set high enough to cover typical scheduling jitter
156  * for a real-time thread.
157  *
158  * @return number of microseconds to delay the wakeup.
159  */
160 int32_t AAudioProperty_getWakeupDelayMicros();
161 #define AAUDIO_PROP_WAKEUP_DELAY_USEC      "aaudio.wakeup_delay_usec"
162 
163 /**
164  * Read a system property that specifies the minimum sleep time when polling the FIFO.
165  *
166  * @return minimum number of microseconds to sleep.
167  */
168 int32_t AAudioProperty_getMinimumSleepMicros();
169 #define AAUDIO_PROP_MINIMUM_SLEEP_USEC      "aaudio.minimum_sleep_usec"
170 
171 /**
172  * Read system property.
173  * This is handy in case the DMA is bursting too quickly for the CPU to keep up.
174  * For example, there may be a DMA burst every 100 usec but you only
175  * want to feed the MMAP buffer every 2000 usec.
176  *
177  * This will affect the framesPerBurst for an MMAP stream.
178  *
179  * @return minimum number of microseconds for a MMAP HW burst
180  */
181 int32_t AAudioProperty_getHardwareBurstMinMicros();
182 #define AAUDIO_PROP_HW_BURST_MIN_USEC      "aaudio.hw_burst_min_usec"
183 
184 /**
185  * Read a system property that specifies an offset that will be added to MMAP timestamps.
186  * This can be used to correct bias in the timestamp.
187  * It can also be used to analyze the time distribution of the timestamp
188  * by progressively modifying the offset and listening for glitches.
189  *
190  * @return number of microseconds to offset the time part of an MMAP timestamp
191  */
192 int32_t AAudioProperty_getInputMMapOffsetMicros();
193 #define AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC    "aaudio.in_mmap_offset_usec"
194 
195 int32_t AAudioProperty_getOutputMMapOffsetMicros();
196 #define AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC   "aaudio.out_mmap_offset_usec"
197 
198 // These are powers of two that can be combined as a bit mask.
199 // AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM must be enabled before the stream is opened.
200 #define AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM   1
201 #define AAUDIO_LOG_RESERVED_2              2
202 #define AAUDIO_LOG_RESERVED_4              4
203 #define AAUDIO_LOG_RESERVED_8              8
204 
205 /**
206  * Use a mask to enable various logs in AAudio.
207  * @return mask that enables various AAudio logs, such as AAUDIO_LOG_CLOCK_MODEL_HISTOGRAM
208  */
209 int32_t AAudioProperty_getLogMask();
210 #define AAUDIO_PROP_LOG_MASK   "aaudio.log_mask"
211 
212 /**
213  * Is flush allowed for the given state?
214  * @param state
215  * @return AAUDIO_OK if allowed or an error
216  */
217 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state);
218 
219 /**
220  * Try a function f until it returns true.
221  *
222  * The function is always called at least once.
223  *
224  * @param f the function to evaluate, which returns a bool.
225  * @param times the number of times to evaluate f.
226  * @param sleepMs the sleep time per check of f, if greater than 0.
227  * @return true if f() eventually returns true.
228  */
AAudio_tryUntilTrue(std::function<bool ()> f,int times,int sleepMs)229 static inline bool AAudio_tryUntilTrue(
230         std::function<bool()> f, int times, int sleepMs) {
231     static const useconds_t US_PER_MS = 1000;
232 
233     sleepMs = std::max(sleepMs, 0);
234     for (;;) {
235         if (f()) return true;
236         if (times <= 1) return false;
237         --times;
238         usleep(sleepMs * US_PER_MS);
239     }
240 }
241 
242 
243 /**
244  * Simple double buffer for a structure that can be written occasionally and read occasionally.
245  * This allows a SINGLE writer with multiple readers.
246  *
247  * It is OK if the FIFO overflows and we lose old values.
248  * It is also OK if we read an old value.
249  * Thread may return a non-atomic result if the other thread is rapidly writing
250  * new values on another core.
251  */
252 template <class T>
253 class SimpleDoubleBuffer {
254 public:
SimpleDoubleBuffer()255     SimpleDoubleBuffer()
256             : mValues() {}
257 
258     __attribute__((no_sanitize("integer")))
write(T value)259     void write(T value) {
260         int index = mCounter.load() & 1;
261         mValues[index] = value;
262         mCounter++; // Increment AFTER updating storage, OK if it wraps.
263     }
264 
265     /**
266      * This should only be called by the same thread that calls write() or when
267      * no other thread is calling write.
268      */
clear()269     void clear() {
270         mCounter.store(0);
271     }
272 
read()273     T read() const {
274         T result;
275         int before;
276         int after;
277         int timeout = 3;
278         do {
279             // Check to see if a write occurred while were reading.
280             before = mCounter.load();
281             int index = (before & 1) ^ 1;
282             result = mValues[index];
283             after = mCounter.load();
284         } while ((after != before) && (after > 0) && (--timeout > 0));
285         return result;
286     }
287 
288     /**
289      * @return true if at least one value has been written
290      */
isValid()291     bool isValid() const {
292         return mCounter.load() > 0;
293     }
294 
295 private:
296     T                    mValues[2];
297     std::atomic<int>     mCounter{0};
298 };
299 
300 class Timestamp {
301 public:
Timestamp()302     Timestamp()
303             : mPosition(0)
304             , mNanoseconds(0) {}
Timestamp(int64_t position,int64_t nanoseconds)305     Timestamp(int64_t position, int64_t nanoseconds)
306             : mPosition(position)
307             , mNanoseconds(nanoseconds) {}
308 
getPosition()309     int64_t getPosition() const { return mPosition; }
310 
getNanoseconds()311     int64_t getNanoseconds() const { return mNanoseconds; }
312 
313 private:
314     // These cannot be const because we need to implement the copy assignment operator.
315     int64_t mPosition;
316     int64_t mNanoseconds;
317 };
318 
319 
320 /**
321  * Pass a request to another thread.
322  * This is used when one thread, A, wants another thread, B, to do something.
323  * A naive approach would be for A to set a flag and for B to clear it when done.
324  * But that creates a race condition. This technique avoids the race condition.
325  *
326  * Assumes only one requester and one acknowledger.
327  */
328 class AtomicRequestor {
329 public:
330 
331     __attribute__((no_sanitize("integer")))
request()332     void request() {
333         mRequested++;
334     }
335 
336     __attribute__((no_sanitize("integer")))
isRequested()337     bool isRequested() {
338         return (mRequested.load() - mAcknowledged.load()) > 0;
339     }
340 
341     __attribute__((no_sanitize("integer")))
acknowledge()342     void acknowledge() {
343         mAcknowledged++;
344     }
345 
346 private:
347     std::atomic<int> mRequested{0};
348     std::atomic<int> mAcknowledged{0};
349 };
350 
351 enum {
352     /**
353      * Audio channel index mask, only used internally.
354      */
355     AAUDIO_CHANNEL_BIT_INDEX = 0x80000000,
356     AAUDIO_CHANNEL_INDEX_MASK_1 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 1) - 1,
357     AAUDIO_CHANNEL_INDEX_MASK_2 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 2) - 1,
358     AAUDIO_CHANNEL_INDEX_MASK_3 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 3) - 1,
359     AAUDIO_CHANNEL_INDEX_MASK_4 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 4) - 1,
360     AAUDIO_CHANNEL_INDEX_MASK_5 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 5) - 1,
361     AAUDIO_CHANNEL_INDEX_MASK_6 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 6) - 1,
362     AAUDIO_CHANNEL_INDEX_MASK_7 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 7) - 1,
363     AAUDIO_CHANNEL_INDEX_MASK_8 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 8) - 1,
364     AAUDIO_CHANNEL_INDEX_MASK_9 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 9) - 1,
365     AAUDIO_CHANNEL_INDEX_MASK_10 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 10) - 1,
366     AAUDIO_CHANNEL_INDEX_MASK_11 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 11) - 1,
367     AAUDIO_CHANNEL_INDEX_MASK_12 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 12) - 1,
368     AAUDIO_CHANNEL_INDEX_MASK_13 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 13) - 1,
369     AAUDIO_CHANNEL_INDEX_MASK_14 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 14) - 1,
370     AAUDIO_CHANNEL_INDEX_MASK_15 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 15) - 1,
371     AAUDIO_CHANNEL_INDEX_MASK_16 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 16) - 1,
372     AAUDIO_CHANNEL_INDEX_MASK_17 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 17) - 1,
373     AAUDIO_CHANNEL_INDEX_MASK_18 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 18) - 1,
374     AAUDIO_CHANNEL_INDEX_MASK_19 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 19) - 1,
375     AAUDIO_CHANNEL_INDEX_MASK_20 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 20) - 1,
376     AAUDIO_CHANNEL_INDEX_MASK_21 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 21) - 1,
377     AAUDIO_CHANNEL_INDEX_MASK_22 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 22) - 1,
378     AAUDIO_CHANNEL_INDEX_MASK_23 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 23) - 1,
379     AAUDIO_CHANNEL_INDEX_MASK_24 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 24) - 1,
380 };
381 
382 #endif //UTILITY_AAUDIO_UTILITIES_H
383