• 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 "volume_ramp.h"
17 #include <cinttypes>
18 #include "audio_log.h"
19 
20 namespace OHOS {
21 namespace AudioStandard {
22 using namespace std;
23 constexpr float MIN_CURVE_TIME = 0.0f;
24 constexpr float MAX_CURVE_TIME = 1.0f;
25 constexpr int32_t MS_PER_S = 1000;
26 constexpr int32_t NS_PER_MS = 1000000;
27 constexpr unsigned long VOLUME_SIZE = 2;
28 
VolumeRamp()29 VolumeRamp::VolumeRamp()
30 {
31     initTime_ = -1;
32     isVolumeRampActive_ = false;
33     rampVolume_ = 1.0f;
34 }
35 
SetVolumeCurve(vector<float> & volumes)36 void VolumeRamp::SetVolumeCurve(vector<float> &volumes)
37 {
38     vector<float> times = {0.0f, 1.0f};
39     CHECK_AND_RETURN_LOG(volumes.size() == VOLUME_SIZE, "Array size must 2!");
40 
41     curvePoints_.clear();
42     for (size_t i = 0; i < times.size(); i++) {
43         curvePoints_.emplace(times[i], volumes[i]);
44     }
45 }
46 
SetVolumeRampConfig(float targetVolume,float currStreamVolume,int32_t duration)47 void VolumeRamp::SetVolumeRampConfig(float targetVolume, float currStreamVolume, int32_t duration)
48 {
49     vector<float> volumes;
50 
51     isVolumeRampActive_ = true;
52     initTime_ = -1;
53     duration_ = duration;
54 
55     if (currStreamVolume > targetVolume) {
56         volumes.assign({targetVolume, currStreamVolume});
57         rampDirection_ = RAMP_DOWN;
58     } else {
59         volumes.assign({currStreamVolume, targetVolume});
60         rampDirection_ = RAMP_UP;
61     }
62     SetVolumeCurve(volumes);
63 }
64 
GetCurrentTimeMS()65 static int64_t GetCurrentTimeMS()
66 {
67     timespec tm {};
68     clock_gettime(CLOCK_MONOTONIC, &tm);
69     return tm.tv_sec * MS_PER_S + (tm.tv_nsec / NS_PER_MS);
70 }
71 
GetRampVolume()72 float VolumeRamp::GetRampVolume()
73 {
74     if (!isVolumeRampActive_) {
75         return rampVolume_;
76     }
77 
78     int64_t currentTime = GetCurrentTimeMS();
79 
80     if (initTime_ < 0) {
81         initTime_ = currentTime;
82         scale_ = 1.0 / duration_;
83     }
84 
85     float scaledTime = GetScaledTime(currentTime);
86     rampVolume_ = FindRampVolume(scaledTime);
87     return rampVolume_;
88 }
89 
GetScaledTime(int64_t currentTime)90 float VolumeRamp::GetScaledTime(int64_t currentTime)
91 {
92     float offset = scale_ * (currentTime - initTime_);
93     if (rampDirection_ == RAMP_DOWN) {
94         offset =  1 - offset;
95         if (offset < MIN_CURVE_TIME) {
96             offset = MIN_CURVE_TIME;
97             isVolumeRampActive_ = false;
98         } else if (offset > MAX_CURVE_TIME) {
99             offset = MAX_CURVE_TIME;
100         }
101     } else {
102         if (offset < MIN_CURVE_TIME) {
103             offset = MIN_CURVE_TIME;
104         } else if (offset > MAX_CURVE_TIME) {
105             offset = MAX_CURVE_TIME;
106             isVolumeRampActive_ = false;
107         }
108     }
109 
110     return offset;
111 }
112 
FindRampVolume(float time)113 float VolumeRamp::FindRampVolume(float time)
114 {
115     auto lowPoint = curvePoints_.begin();
116     auto highPoint = curvePoints_.rbegin();
117 
118     float volume = lowPoint->second + ((time - lowPoint->first) / (highPoint->first - lowPoint->first))
119         * (highPoint->second - lowPoint->second);
120     return volume;
121 }
122 
IsActive()123 bool VolumeRamp::IsActive()
124 {
125     return isVolumeRampActive_;
126 }
127 
Terminate()128 void VolumeRamp::Terminate()
129 {
130     isVolumeRampActive_ = false;
131 }
132 } // namespace AudioStandard
133 } // namespace OHOS
134