1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef AUDIO_UTILS_H
16 #define AUDIO_UTILS_H
17
18 #include <cstdint>
19 #include <string>
20 #include <map>
21 #include <unordered_map>
22 #include <mutex>
23 #include <ctime>
24 #include <sys/time.h>
25 #include <atomic>
26 #include <cstdio>
27 #include <queue>
28 #include <climits>
29 #include <condition_variable>
30 #include "securec.h"
31 #include <unistd.h>
32 #include "audio_info.h"
33
34 #define AUDIO_MS_PER_SECOND 1000
35 #define AUDIO_US_PER_SECOND 1000000
36 #define AUDIO_NS_PER_SECOND ((uint64_t)1000000000)
37
38 #define FLOAT_EPS 1e-9f
39 #define OFFSET_BIT_24 3
40 #define BIT_DEPTH_TWO 2
41 #define BIT_8 8
42 #define BIT_16 16
43 #define BIT_24 24
44 #define BIT_32 32
45 namespace OHOS {
46 namespace AudioStandard {
47 const int64_t PCM_MAYBE_SILENT = 1;
48 const int64_t PCM_MAYBE_NOT_SILENT = 5;
49 const int32_t SIGNAL_DATA_SIZE = 96;
50 const int32_t SIGNAL_THRESHOLD = 10;
51 const int32_t BLANK_THRESHOLD_MS = 100;
52 const int32_t DETECTED_ZERO_THRESHOLD = 1;
53 const size_t MILLISECOND_PER_SECOND = 1000;
54 const int64_t DEFAULT_TIMEOUT_NS = 40 * 1000 * 1000;
55 const size_t MOCK_INTERVAL = 2000;
56 const int32_t GET_EXTRA_PARAM_LEN = 200;
57 const int32_t YEAR_BASE = 1900;
58 const int32_t DECIMAL_EXPONENT = 10;
59 const size_t DATE_LENGTH = 17;
60 static uint32_t g_sessionToMock = 0;
61 const uint32_t MAX_VALUE_OF_SIGNED_24_BIT = 8388607;
62 const uint32_t STRING_BUFFER_SIZE = 4096;
63
64 // Ringer or alarmer dual tone
65 const size_t AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT = 2;
66
67 /* Define AudioXcollie timeout flag, consistent with xcollie_define.h in hiviewdfx */
68 static constexpr unsigned int AUDIO_XCOLLIE_FLAG_DEFAULT = (~0); // do all callback function
69 static constexpr unsigned int AUDIO_XCOLLIE_FLAG_NOOP = (0); // do nothing but the caller defined function
70 static constexpr unsigned int AUDIO_XCOLLIE_FLAG_LOG = (1 << 0); // generate log file
71 static constexpr unsigned int AUDIO_XCOLLIE_FLAG_RECOVERY = (1 << 1); // die when timeout
72
73 class Util {
74 public:
75 static bool IsDualToneStreamType(const AudioStreamType streamType);
76
77 static bool IsRingerOrAlarmerStreamUsage(const StreamUsage &usage);
78
79 static bool IsRingerAudioScene(const AudioScene &audioScene);
80
81 static uint32_t GetSamplePerFrame(const AudioSampleFormat &format);
82 };
83
84 class Trace {
85 public:
86 static void Count(const std::string &value, int64_t count);
87 // Show if data is silent.
88 static void CountVolume(const std::string &value, uint8_t data);
89 Trace(const std::string &value);
90 void End();
91 ~Trace();
92 private:
93 std::string value_;
94 bool isFinished_;
95 };
96
97 class AudioXCollie {
98 public:
99 AudioXCollie(const std::string &tag, uint32_t timeoutSeconds,
100 std::function<void(void *)> func = nullptr, void *arg = nullptr, uint32_t flag = 1);
101 ~AudioXCollie();
102 void CancelXCollieTimer();
103 private:
104 int32_t id_;
105 std::string tag_;
106 bool isCanceled_;
107 };
108
109 class ClockTime {
110 public:
111 static int64_t GetCurNano();
112 static int64_t GetRealNano();
113 static int32_t AbsoluteSleep(int64_t nanoTime);
114 static int32_t RelativeSleep(int64_t nanoTime);
115 static std::string NanoTimeToString(int64_t nanoTime);
116 };
117
118 /**
119 * Example 1: Use specific timeout call Check().
120 * WatchTimeout guard("DoSomeWorkFunction", 50 * AUDIO_US_PER_SECOND); // if func cost more than 50 ms, print log
121 * DoSomeWorkFunction();
122 * guard.CheckCurrTimeout();
123 * Example 2: Use default timeout(40ms) and auto-check in release.
124 * WatchTimeout guard("DoSomeWorkFunction")
125 * DoSomeWorkFunction();
126 */
127 class WatchTimeout {
128 public:
129 WatchTimeout(const std::string &funcName, int64_t timeoutNs = DEFAULT_TIMEOUT_NS);
130 ~WatchTimeout();
131 void CheckCurrTimeout();
132 private:
133 const std::string funcName_;
134 int64_t timeoutNs_ = 0;
135 int64_t startTimeNs_ = 0;
136 bool isChecked_ = false;
137 };
138
139 class PermissionUtil {
140 public:
141 static bool VerifyIsAudio();
142 static bool VerifyIsShell();
143 static bool VerifyIsSystemApp();
144 static bool VerifySelfPermission();
145 static bool VerifySystemPermission();
146 static bool VerifyPermission(const std::string &permissionName, uint32_t tokenId);
147 static bool NeedVerifyBackgroundCapture(int32_t callingUid, SourceType sourceType);
148 static bool VerifyBackgroundCapture(uint32_t tokenId, uint64_t fullTokenId);
149 static bool NotifyStart(uint32_t targetTokenId, uint32_t sessionId);
150 static bool NotifyStop(uint32_t targetTokenId, uint32_t sessionId);
151 };
152
153 void AdjustStereoToMonoForPCM8Bit(int8_t *data, uint64_t len);
154 void AdjustStereoToMonoForPCM16Bit(int16_t *data, uint64_t len);
155 void AdjustStereoToMonoForPCM24Bit(int8_t *data, uint64_t len);
156 void AdjustStereoToMonoForPCM32Bit(int32_t *data, uint64_t len);
157 void AdjustAudioBalanceForPCM8Bit(int8_t *data, uint64_t len, float left, float right);
158 void AdjustAudioBalanceForPCM16Bit(int16_t *data, uint64_t len, float left, float right);
159 void AdjustAudioBalanceForPCM24Bit(int8_t *data, uint64_t len, float left, float right);
160 void AdjustAudioBalanceForPCM32Bit(int32_t *data, uint64_t len, float left, float right);
161
162 void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b);
163 void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b);
164 void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b);
165 void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b);
166
167 std::string GetEncryptStr(const std::string &str);
168 std::string ConvertNetworkId(const std::string &networkId);
169
170 enum ConvertHdiFormat {
171 SAMPLE_U8_C = 0,
172 SAMPLE_S16_C = 1,
173 SAMPLE_S24_C = 2,
174 SAMPLE_S32_C = 3,
175 SAMPLE_F32_C = 4,
176 INVALID_WIDTH_C = -1
177 }; // same with HdiAdapterFormat
178
179 float UpdateMaxAmplitude(ConvertHdiFormat adapterFormat, char *frame, uint64_t replyBytes);
180 float CalculateMaxAmplitudeForPCM8Bit(int8_t *frame, uint64_t nSamples);
181 float CalculateMaxAmplitudeForPCM16Bit(int16_t *frame, uint64_t nSamples);
182 float CalculateMaxAmplitudeForPCM24Bit(char *frame, uint64_t nSamples);
183 float CalculateMaxAmplitudeForPCM32Bit(int32_t *frame, uint64_t nSamples);
184
185 template <typename T>
186 bool isEqual(T a, T b, double precision = 0.01)
187 {
188 return std::abs(a - b) < precision;
189 }
190
191 // return true if value is not in the array.
192 template <typename V>
NotContain(const std::vector<V> & array,const V & value)193 inline bool NotContain(const std::vector<V> &array, const V &value)
194 {
195 return std::find(array.begin(), array.end(), value) == array.end();
196 }
197
198 bool SetSysPara(const std::string& key, int32_t value);
199 template <typename T>
200 bool GetSysPara(const char *key, T &value);
201
202 enum AudioDumpFileType {
203 AUDIO_APP = 0,
204 OTHER_NATIVE_SERVICE = 1,
205 AUDIO_PULSE = 2,
206 };
207
208 const std::string DUMP_SERVER_PARA = "sys.audio.dump.writeserver.enable";
209 const std::string DUMP_CLIENT_PARA = "sys.audio.dump.writeclient.enable";
210 const std::string DUMP_PULSE_DIR = "/data/data/.pulse_dir/";
211 const std::string DUMP_SERVICE_DIR = "/data/local/tmp/";
212 const std::string DUMP_APP_DIR = "/data/storage/el2/base/cache/";
213 const std::string DUMP_BLUETOOTH_RENDER_SINK_FILENAME = "dump_bluetooth_audiosink.pcm";
214 const std::string DUMP_RENDER_SINK_FILENAME = "dump_audiosink.pcm";
215 const std::string DUMP_MCH_SINK_FILENAME = "dump_mchaudiosink.pcm";
216 const std::string DUMP_DIRECT_RENDER_SINK_FILENAME = "dump_direct_audiosink.pcm";
217 const std::string DUMP_OFFLOAD_RENDER_SINK_FILENAME = "dump_offloadaudiosink.pcm";
218 const std::string DUMP_CAPTURER_SOURCE_FILENAME = "dump_capture_audiosource.pcm";
219 const std::string DUMP_TONEPLAYER_FILENAME = "dump_toneplayer_audio.pcm";
220 const std::string DUMP_PROCESS_IN_CLIENT_FILENAME = "dump_process_client_audio.pcm";
221 const std::string DUMP_REMOTE_RENDER_SINK_FILENAME = "dump_remote_audiosink";
222 const std::string DUMP_REMOTE_CAPTURE_SOURCE_FILENAME = "dump_remote_capture_audiosource.pcm";
223 const uint32_t PARAM_VALUE_LENTH = 150;
224 const std::string BETA_VERSION = "beta";
225
226 class DumpFileUtil {
227 public:
228 static void WriteDumpFile(FILE *dumpFile, void *buffer, size_t bufferSize);
229 static void CloseDumpFile(FILE **dumpFile);
230 static std::map<std::string, std::string> g_lastPara;
231 static void OpenDumpFile(std::string para, std::string fileName, FILE **file);
232 private:
233 static FILE *OpenDumpFileInner(std::string para, std::string fileName, AudioDumpFileType fileType);
234 static void ChangeDumpFileState(std::string para, FILE **dumpFile, std::string fileName);
235 };
236
237 template <typename...Args>
AppendFormat(std::string & out,const char * fmt,Args &&...args)238 void AppendFormat(std::string& out, const char* fmt, Args&& ... args)
239 {
240 char buf[STRING_BUFFER_SIZE] = {0};
241 int len = ::sprintf_s(buf, sizeof(buf), fmt, args...);
242 if (len <= 0) {
243 return;
244 }
245 out += buf;
246 }
247
248 class AudioInfoDumpUtils {
249 public:
250 static const std::string GetStreamName(AudioStreamType streamType);
251 static const std::string GetDeviceTypeName(DeviceType deviceType);
252 static const std::string GetConnectTypeName(ConnectType connectType);
253 static const std::string GetSourceName(SourceType sourceType);
254 static const std::string GetDeviceVolumeTypeName(DeviceVolumeType deviceType);
255 };
256
257 class VolumeUtils {
258 public:
259 static AudioVolumeType GetVolumeTypeFromStreamType(AudioStreamType streamType);
260
261 private:
262 static std::unordered_map<AudioStreamType, AudioVolumeType> defaultVolumeMap_;
263 static std::unordered_map<AudioStreamType, AudioVolumeType>& GetVolumeMap();
264 };
265
266 template<typename T>
267 class ObjectRefMap {
268 public:
269 static std::mutex allObjLock;
270 static std::map<T*, uint32_t> refMap;
271 static void Insert(T *obj);
272 static void Erase(T *obj);
273 static T *IncreaseRef(T *obj);
274 static void DecreaseRef(T *obj);
275
276 ObjectRefMap(T *obj);
277 ~ObjectRefMap();
278 T *GetPtr();
279
280 private:
281 T *obj_ = nullptr;
282 };
283
284 template <typename T>
285 std::mutex ObjectRefMap<T>::allObjLock;
286
287 template <typename T>
288 std::map<T *, uint32_t> ObjectRefMap<T>::refMap;
289
290 template <typename T>
Insert(T * obj)291 void ObjectRefMap<T>::Insert(T *obj)
292 {
293 std::lock_guard<std::mutex> lock(allObjLock);
294 refMap[obj] = 1;
295 }
296
297 template <typename T>
Erase(T * obj)298 void ObjectRefMap<T>::Erase(T *obj)
299 {
300 std::lock_guard<std::mutex> lock(allObjLock);
301 auto it = refMap.find(obj);
302 if (it != refMap.end()) {
303 refMap.erase(it);
304 }
305 }
306
307 template <typename T>
IncreaseRef(T * obj)308 T *ObjectRefMap<T>::IncreaseRef(T *obj)
309 {
310 std::lock_guard<std::mutex> lock(allObjLock);
311 if (refMap.count(obj)) {
312 refMap[obj]++;
313 return obj;
314 } else {
315 return nullptr;
316 }
317 }
318
319 template <typename T>
DecreaseRef(T * obj)320 void ObjectRefMap<T>::DecreaseRef(T *obj)
321 {
322 std::lock_guard<std::mutex> lock(allObjLock);
323 if (refMap.count(obj) && --refMap[obj] == 0) {
324 refMap.erase(obj);
325 delete obj;
326 obj = nullptr;
327 }
328 }
329
330 template <typename T>
ObjectRefMap(T * obj)331 ObjectRefMap<T>::ObjectRefMap(T *obj)
332 {
333 if (obj != nullptr) {
334 obj_ = ObjectRefMap::IncreaseRef(obj);
335 }
336 }
337
338 template <typename T>
~ObjectRefMap()339 ObjectRefMap<T>::~ObjectRefMap()
340 {
341 if (obj_ != nullptr) {
342 ObjectRefMap::DecreaseRef(obj_);
343 }
344 }
345
346 template <typename T>
GetPtr()347 T *ObjectRefMap<T>::GetPtr()
348 {
349 return obj_;
350 }
351
352 std::string GetTime();
353
354 int32_t GetFormatByteSize(int32_t format);
355
356 struct SignalDetectAgent {
357 bool CheckAudioData(uint8_t *buffer, size_t bufferLen);
358 bool DetectSignalData(int32_t *buffer, size_t bufferLen);
359 void ResetDetectResult();
360 int32_t channels_ = STEREO;
361 int32_t sampleRate_ = SAMPLE_RATE_48000;
362 int32_t sampleFormat_ = SAMPLE_S16LE;
363 int32_t formatByteSize_;
364 int32_t lastPeakSignal_ = SHRT_MIN;
365 int32_t lastPeakSignalPos_ = 0;
366 int32_t blankPeriod_ = 0;
367 size_t frameCountIgnoreChannel_;
368 bool hasFirstNoneZero_ = false;
369 bool blankHaveOutput_ = true;
370 bool dspTimestampGot_ = false;
371 bool signalDetected_ = false;
372 std::string lastPeakBufferTime_ = "";
373 std::vector<int32_t> cacheAudioData_;
374 };
375
376 class AudioLatencyMeasurement {
377 public:
378 // static methods, invoked without instantiation in sinks and sources
379 static bool CheckIfEnabled();
380 AudioLatencyMeasurement(const int32_t &sampleRate, const int32_t &channelCount,
381 const int32_t &sampleFormat, const std::string &appName, const uint32_t &sessionId);
382 ~AudioLatencyMeasurement();
383
384 // non-static methods, invoked after instantiation in AudioRenderer and AudioCapturer
385 void InitSignalData();
386 bool MockPcmData(uint8_t *buffer, size_t bufferLen); // mute data and insert signal data
387 private:
388 int32_t format_ = SAMPLE_S16LE;
389 int32_t formatByteSize_;
390 int32_t sampleRate_;
391 int32_t channelCount_;
392 uint32_t sessionId_;
393 size_t mockedTime_ = 0;
394 bool mockThisStream_ = false;
395 std::string appName_;
396 std::unique_ptr<int16_t[]> signalData_ = nullptr;
397 };
398
399 class LatencyMonitor {
400 public:
401 static LatencyMonitor& GetInstance();
402 void ShowTimestamp(bool isRenderer);
403 void ShowBluetoothTimestamp();
404 void UpdateClientTime(bool isRenderer, std::string ×tamp);
405 void UpdateSinkOrSourceTime(bool isRenderer, std::string ×tamp);
406 void UpdateDspTime(std::string dspTime);
407 private:
408 std::string rendererMockTime_ = "";
409 std::string sinkDetectedTime_ = "";
410 std::string dspDetectedTime_ = "";
411 std::string capturerDetectedTime_ = "";
412 std::string sourceDetectedTime_ = "";
413 std::string dspBeforeSmartPa_ = "";
414 std::string dspAfterSmartPa_ = "";
415 std::string dspMockTime_ = "";
416 size_t extraStrLen_ = 0;
417 };
418
419 class AudioDump {
420 public:
421 static AudioDump& GetInstance();
422 void SetVersionType(const std::string& versionType);
423 std::string GetVersionType();
424 private:
AudioDump()425 AudioDump() {}
~AudioDump()426 ~AudioDump() {}
427 std::string versionType_ = "commercial";
428 };
429
430 template <typename EnumType, typename V>
GetKeyFromValue(const std::unordered_map<EnumType,V> & map,const V & value)431 int32_t GetKeyFromValue(const std::unordered_map<EnumType, V> &map, const V &value)
432 {
433 for (auto it : map) {
434 if (it.second == value) {
435 return it.first;
436 }
437 }
438 return -1;
439 }
440
441 template <typename T, typename Compare>
CasWithCompare(std::atomic<T> & atomicVar,T newValue,Compare compare)442 bool CasWithCompare(std::atomic<T> &atomicVar, T newValue, Compare compare)
443 {
444 T old = atomicVar;
445 do {
446 if (!compare(old, newValue)) {
447 return false;
448 }
449 } while (!atomicVar.compare_exchange_weak(old, newValue));
450
451 return true;
452 }
453
454 /**
455 * @brief Provides interfaces for thread-safe blocking queues.
456 *
457 * The interfaces can be used to perform blocking and non-blocking push and
458 * pop operations on queues.
459 */
460 template <typename T>
461 class AudioSafeBlockQueue {
462 public:
AudioSafeBlockQueue(int capacity)463 explicit AudioSafeBlockQueue(int capacity) : maxSize_(capacity)
464 {
465 }
466
467 /**
468 * @brief Inserts an element at the end of this queue in blocking mode.
469 *
470 * If the queue is full, the thread of the push operation will be blocked
471 * until the queue has space.
472 * If the queue is not full, the push operation can be performed and one of the
473 * pop threads (blocked when the queue is empty) is woken up.
474 *
475 * @param elem Indicates the element to insert.
476 */
Push(T const & elem)477 virtual void Push(T const& elem)
478 {
479 std::unique_lock<std::mutex> lock(mutexLock_);
480 while (queueT_.size() >= maxSize_) {
481 // If the queue is full, wait for jobs to be taken.
482 cvNotFull_.wait(lock, [&]() { return (queueT_.size() < maxSize_); });
483 }
484
485 // Insert the element into the queue if the queue is not full.
486 queueT_.push(elem);
487 cvNotEmpty_.notify_all();
488 }
489
490 /**
491 * @brief Removes the first element from this queue in blocking mode.
492 *
493 * If the queue is empty, the thread of the pop operation will be blocked
494 * until the queue has elements.
495 * If the queue is not empty, the pop operation can be performed, the first
496 * element of the queue is returned, and one of the push threads (blocked
497 * when the queue is full) is woken up.
498 */
Pop()499 T Pop()
500 {
501 std::unique_lock<std::mutex> lock(mutexLock_);
502
503 while (queueT_.empty()) {
504 // If the queue is empty, wait for elements to be pushed in.
505 cvNotEmpty_.wait(lock, [&] { return !queueT_.empty(); });
506 }
507
508 T elem = queueT_.front();
509 queueT_.pop();
510 cvNotFull_.notify_all();
511 return elem;
512 }
513
514 /**
515 * @brief Inserts an element at the end of this queue in non-blocking mode.
516 *
517 * If the queue is full, <b>false</b> is returned directly.
518 * If the queue is not full, the push operation can be performed, one of the
519 * pop threads (blocked when the queue is empty) is woken up, and <b>true</b>
520 * is returned.
521 *
522 * @param elem Indicates the element to insert.
523 */
PushNoWait(T const & elem)524 virtual bool PushNoWait(T const& elem)
525 {
526 std::unique_lock<std::mutex> lock(mutexLock_);
527 if (queueT_.size() >= maxSize_) {
528 return false;
529 }
530 // Insert the element if the queue is not full.
531 queueT_.push(elem);
532 cvNotEmpty_.notify_all();
533 return true;
534 }
535
536 /**
537 * @brief Removes the first element from this queue in non-blocking mode.
538 *
539 * If the queue is empty, <b>false</b> is returned directly.
540 * If the queue is not empty, the pop operation can be performed, one of the
541 * push threads (blocked when the queue is full) is woken up, and <b>true</b>
542 * is returned.
543 *
544 * @param outtask Indicates the data of the pop operation.
545 */
PopNotWait(T & outtask)546 bool PopNotWait(T& outtask)
547 {
548 std::unique_lock<std::mutex> lock(mutexLock_);
549 if (queueT_.empty()) {
550 return false;
551 }
552 outtask = queueT_.front();
553 queueT_.pop();
554
555 cvNotFull_.notify_all();
556
557 return true;
558 }
559
PopAllNotWait()560 std::queue<T> PopAllNotWait()
561 {
562 std::queue<T> retQueue = {};
563 std::unique_lock<std::mutex> lock(mutexLock_);
564 retQueue.swap(queueT_);
565
566 cvNotFull_.notify_all();
567
568 return retQueue;
569 }
570
Size()571 unsigned int Size()
572 {
573 std::unique_lock<std::mutex> lock(mutexLock_);
574 return queueT_.size();
575 }
576
577 template< class Rep, class Period >
WaitNotEmptyFor(const std::chrono::duration<Rep,Period> & rel_time)578 void WaitNotEmptyFor(const std::chrono::duration<Rep, Period>& rel_time)
579 {
580 std::unique_lock<std::mutex> lock(mutexLock_);
581 cvNotEmpty_.wait_for(lock, rel_time, [this] {
582 return !queueT_.empty();
583 });
584 }
585
IsEmpty()586 bool IsEmpty()
587 {
588 std::unique_lock<std::mutex> lock(mutexLock_);
589 return queueT_.empty();
590 }
591
IsFull()592 bool IsFull()
593 {
594 std::unique_lock<std::mutex> lock(mutexLock_);
595 return queueT_.size() == maxSize_;
596 }
597
Clear()598 void Clear()
599 {
600 std::unique_lock<std::mutex> lock(mutexLock_);
601 queueT_ = {};
602 cvNotFull_.notify_all();
603 }
604
~AudioSafeBlockQueue()605 virtual ~AudioSafeBlockQueue() {}
606
607 protected:
608 unsigned long maxSize_; // Capacity of the queue
609 std::mutex mutexLock_;
610 std::condition_variable cvNotEmpty_;
611 std::condition_variable cvNotFull_;
612 std::queue<T> queueT_;
613 };
614
615 enum AudioHdiUniqueIDBase : uint32_t {
616 // 0-4 is reserved for other modules
617 AUDIO_HDI_RENDER_ID_BASE = 5,
618 AUDIO_HDI_CAPTURE_ID_BASE = 6,
619 };
620
621 enum HdiCaptureOffset : uint32_t {
622 HDI_CAPTURE_OFFSET_PRIMARY = 1,
623 HDI_CAPTURE_OFFSET_FAST = 2,
624 HDI_CAPTURE_OFFSET_REMOTE = 3,
625 HDI_CAPTURE_OFFSET_REMOTE_FAST = 4,
626 HDI_CAPTURE_OFFSET_USB = 5,
627 HDI_CAPTURE_OFFSET_EC = 6,
628 HDI_CAPTURE_OFFSET_MIC_REF = 7,
629 HDI_CAPTURE_OFFSET_WAKEUP = 8,
630 };
631
632 enum HdiRenderOffset : uint32_t {
633 HDI_RENDER_OFFSET_PRIMARY = 1,
634 HDI_RENDER_OFFSET_FAST = 2,
635 HDI_RENDER_OFFSET_REMOTE = 3,
636 HDI_RENDER_OFFSET_REMOTE_FAST = 4,
637 HDI_RENDER_OFFSET_BLUETOOTH = 5,
638 HDI_RENDER_OFFSET_OFFLOAD = 6,
639 HDI_RENDER_OFFSET_MULTICHANNEL = 7,
640 HDI_RENDER_OFFSET_DIRECT = 8,
641 HDI_RENDER_OFFSET_VOIP = 9,
642 HDI_RENDER_OFFSET_DP = 10,
643 HDI_RENDER_OFFSET_USB = 11,
644 HDI_RENDER_OFFSET_VOIP_FAST = 12,
645 };
646
647 uint32_t GenerateUniqueID(AudioHdiUniqueIDBase base, uint32_t offset);
648
649 void CloseFd(int fd);
650 } // namespace AudioStandard
651 } // namespace OHOS
652 #endif // AUDIO_UTILS_H
653