• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "linear_pos_time_model.h"
17 
18 #include <cinttypes>
19 
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 
23 namespace OHOS {
24 namespace AudioStandard {
25 namespace {
26     static constexpr int64_t NANO_COUNT_PER_SECOND = 1000000000;
27     static constexpr int32_t MAX_SUPPORT_SAMPLE_RETE = 384000;
28     static constexpr int64_t REASONABLE_BOUND_IN_NANO = 10000000; // 10ms
29 }
LinearPosTimeModel()30 LinearPosTimeModel::LinearPosTimeModel()
31 {
32     AUDIO_INFO_LOG("New LinearPosTimeModel");
33 }
34 
ConfigSampleRate(int32_t sampleRate)35 bool LinearPosTimeModel::ConfigSampleRate(int32_t sampleRate)
36 {
37     AUDIO_INFO_LOG("ConfigSampleRate:%{public}d", sampleRate);
38     if (isConfiged) {
39         AUDIO_ERR_LOG("SampleRate already set:%{public}d", sampleRate_);
40         return false;
41     }
42     sampleRate_ = sampleRate;
43     if (sampleRate_ <= 0 || sampleRate_ > MAX_SUPPORT_SAMPLE_RETE) {
44         AUDIO_ERR_LOG("Invalid sample rate!");
45         return false;
46     } else {
47         nanoTimePerFrame_ = NANO_COUNT_PER_SECOND / sampleRate;
48     }
49     isConfiged = true;
50     return true;
51 }
52 
ResetFrameStamp(uint64_t frame,int64_t nanoTime)53 void LinearPosTimeModel::ResetFrameStamp(uint64_t frame, int64_t nanoTime)
54 {
55     AUDIO_INFO_LOG("Reset frame:%{public}" PRIu64" with time:%{public}" PRId64".", frame, nanoTime);
56     stampFrame_ = frame;
57     stampNanoTime_ = nanoTime;
58     return;
59 }
60 
IsReasonable(uint64_t frame,int64_t nanoTime)61 bool LinearPosTimeModel::IsReasonable(uint64_t frame, int64_t nanoTime)
62 {
63     if (frame == stampFrame_ && nanoTime == stampNanoTime_) {
64         return true;
65     }
66     int64_t deltaFrame = 0;
67     int64_t reasonableDeltaTime = 0;
68     if (frame > stampFrame_) {
69         deltaFrame = static_cast<int64_t>(frame - stampFrame_);
70     } else {
71         deltaFrame = -static_cast<int64_t>(stampFrame_ - frame);
72     }
73     reasonableDeltaTime = stampNanoTime_ + deltaFrame * NANO_COUNT_PER_SECOND / (int64_t)sampleRate_;
74 
75     // note: compare it with current time?
76     if (nanoTime <= (reasonableDeltaTime + REASONABLE_BOUND_IN_NANO) &&
77         nanoTime >= (reasonableDeltaTime - REASONABLE_BOUND_IN_NANO)) {
78         return true;
79     }
80     return false;
81 }
82 
UpdataFrameStamp(uint64_t frame,int64_t nanoTime)83 bool LinearPosTimeModel::UpdataFrameStamp(uint64_t frame, int64_t nanoTime)
84 {
85     if (IsReasonable(frame, nanoTime)) {
86         AUDIO_INFO_LOG("Updata frame:%{public}" PRIu64" with time:%{public}" PRId64".", frame, nanoTime);
87         stampFrame_ = frame;
88         stampNanoTime_ = nanoTime;
89         return true;
90     }
91     AUDIO_WARNING_LOG("Unreasonable pos-time[ %{public}" PRIu64" %{public}" PRId64"] "
92         " stamp pos-time[ %{public}" PRIu64" %{public}" PRId64"].", frame, nanoTime, stampFrame_, stampNanoTime_);
93     // note: keep it in queue.
94     return false;
95 }
96 
GetFrameStamp(uint64_t & frame,int64_t & nanoTime)97 bool LinearPosTimeModel::GetFrameStamp(uint64_t &frame, int64_t &nanoTime)
98 {
99     if (!isConfiged) {
100         AUDIO_ERR_LOG("GetFrameStamp is not configed!");
101         return false;
102     }
103     frame = stampFrame_;
104     nanoTime = stampNanoTime_;
105     return true;
106 }
107 
SetSpanCount(uint64_t spanCountInFrame)108 void LinearPosTimeModel::SetSpanCount(uint64_t spanCountInFrame)
109 {
110     AUDIO_INFO_LOG("New spanCountInFrame:%{public}" PRIu64".", spanCountInFrame);
111     spanCountInFrame_ = spanCountInFrame;
112     return;
113 }
114 
GetTimeOfPos(uint64_t posInFrame)115 int64_t LinearPosTimeModel::GetTimeOfPos(uint64_t posInFrame)
116 {
117     int64_t deltaFrame = 0;
118     int64_t invalidTime = -1;
119     if (!isConfiged) {
120         AUDIO_ERR_LOG("SampleRate is not configed!");
121         return invalidTime;
122     }
123     if (posInFrame >= stampFrame_) {
124         CHECK_AND_BREAK_LOG((posInFrame - stampFrame_ < (uint64_t)sampleRate_), "posInFrame %{public}" PRIu64" is too"
125             " large, stampFrame: %{public}" PRIu64"", posInFrame, stampFrame_);
126         deltaFrame = posInFrame - stampFrame_;
127         return stampNanoTime_ + deltaFrame * NANO_COUNT_PER_SECOND / (int64_t)sampleRate_;
128     } else {
129         CHECK_AND_BREAK_LOG((stampFrame_ - posInFrame < (uint64_t)sampleRate_), "posInFrame %{public}" PRIu64" is too"
130             " small, stampFrame: %{public}" PRIu64"", posInFrame, stampFrame_);
131         deltaFrame = stampFrame_ - posInFrame;
132         return stampNanoTime_ - deltaFrame * NANO_COUNT_PER_SECOND / (int64_t)sampleRate_;
133     }
134     return invalidTime;
135 }
136 } // namespace AudioStandard
137 } // namespace OHOS
138 
139