1 /*
2 * Copyright (c) 2025 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
16 #ifndef LOG_TAG
17 #define LOG_TAG "CapturerClock"
18 #endif
19
20 #include "capturer_clock.h"
21 #include <limits>
22 #include <cinttypes>
23 #include "audio_hdi_log.h"
24 #include "audio_utils.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
28
CapturerClock(uint32_t capturerSampleRate)29 CapturerClock::CapturerClock(uint32_t capturerSampleRate)
30 : capturerSampleRate_(capturerSampleRate)
31 {
32 AUDIO_INFO_LOG("Created, capturer sampling rate:%{public}u", capturerSampleRate);
33 }
34
GetTimeStampByPosition(uint64_t capturerPos,uint64_t & timestamp)35 bool CapturerClock::GetTimeStampByPosition(uint64_t capturerPos, uint64_t& timestamp)
36 {
37 std::lock_guard<std::mutex> lock(clockMtx_);
38 CHECK_AND_RETURN_RET(timestamp_ != 0, false);
39 CHECK_AND_RETURN_RET_LOG(capturerSampleRate_ != 0, false, "capturerSampleRate_ is 0!");
40
41 AUDIO_DEBUG_LOG("capturerPos:%{public}" PRIu64 " position_:%{public}" PRIu64,
42 capturerPos, position_);
43
44 if (capturerPos == position_) {
45 timestamp = timestamp_;
46 AUDIO_DEBUG_LOG("timestamp:%{public}" PRIu64, timestamp);
47 return true;
48 }
49
50 // If the requested position does not equal the clock position,
51 // the timestamp to returned is estimated using the clock position.
52 uint64_t posDetla = 0;
53 uint64_t tsDetla = 0;
54 if (position_ > capturerPos) {
55 posDetla = position_ - capturerPos;
56 tsDetla = posDetla * AUDIO_NS_PER_SECOND / capturerSampleRate_;
57 timestamp = timestamp_ - tsDetla;
58 } else {
59 posDetla = capturerPos - position_;
60 tsDetla = posDetla * AUDIO_NS_PER_SECOND / capturerSampleRate_;
61 timestamp = timestamp_ + tsDetla;
62 }
63 AUDIO_DEBUG_LOG("timestamp:%{public}" PRIu64 "posDetla:%{public}" PRIu64
64 " tsDetla:%{public}" PRIu64, timestamp, posDetla, tsDetla);
65 return true;
66 }
67
SetTimeStampByPosition(uint64_t timestamp,uint32_t srcSampleRate,uint64_t posIncSize)68 void CapturerClock::SetTimeStampByPosition(
69 uint64_t timestamp, uint32_t srcSampleRate, uint64_t posIncSize)
70 {
71 AUDIO_DEBUG_LOG("timestamp:%{public}" PRIu64 " srcSr:%{public}u posIncSize:%{public}" PRIu64,
72 timestamp, srcSampleRate, posIncSize);
73
74 std::lock_guard<std::mutex> lock(clockMtx_);
75 CHECK_AND_RETURN_LOG(isRunning_, "clock is pause! stop update!");
76
77 // When source sampling rate is different from sampling rate required by the upper-level session,
78 // it is necessary to convert source position increase into upper-level position increase.
79 if (srcSampleRate != capturerSampleRate_) {
80 double ratio = static_cast<double>(capturerSampleRate_) / srcSampleRate;
81 posIncSize = posIncSize * ratio;
82 }
83
84 // The updating position rule :
85 // 1. Add the previous position increase (previous buffer size) to the current position.
86 // 2. The size of the audio buffer uploaded this time is saved for adding to the next time.
87 position_ += lastPosInc_;
88 lastPosInc_ = posIncSize;
89 timestamp_ = timestamp;
90 }
91
Start()92 void CapturerClock::Start()
93 {
94 AUDIO_INFO_LOG("CapturerClock is start!");
95
96 std::lock_guard<std::mutex> lock(clockMtx_);
97 isRunning_ = true;
98 }
99
Stop()100 void CapturerClock::Stop()
101 {
102 AUDIO_INFO_LOG("CapturerClock is Stop!");
103
104 std::lock_guard<std::mutex> lock(clockMtx_);
105 isRunning_ = false;
106 }
107
108 } // namespace AudioStandard
109 } // namespace OHOS
110