• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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