Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: chromecast/media/cma/backend/alsa/slew_volume.cc

Issue 2860673003: [Chromecast] Correct libcast_governor behavior. (Closed)
Patch Set: Remove debug logging Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromecast/media/cma/backend/alsa/slew_volume.h" 5 #include "chromecast/media/cma/backend/alsa/slew_volume.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/vector_math.h" 10 #include "media/base/vector_math.h"
11 11
12 namespace { 12 namespace {
13 13
14 // The time to slew from current volume to target volume. 14 // The time to slew from current volume to target volume.
15 const int kMaxSlewTimeMs = 100; 15 const int kMaxSlewTimeMs = 100;
16 const int kDefaultSampleRate = 44100; 16 const int kDefaultSampleRate = 44100;
17 } 17
18 } // namespace
18 19
19 namespace chromecast { 20 namespace chromecast {
20 namespace media { 21 namespace media {
21 22
22 SlewVolume::SlewVolume() : SlewVolume(kMaxSlewTimeMs) {} 23 SlewVolume::SlewVolume() : SlewVolume(kMaxSlewTimeMs) {}
23 24
24 SlewVolume::SlewVolume(int max_slew_time_ms) 25 SlewVolume::SlewVolume(int max_slew_time_ms)
25 : sample_rate_(kDefaultSampleRate), 26 : sample_rate_(kDefaultSampleRate),
26 max_slew_time_ms_(max_slew_time_ms), 27 max_slew_time_ms_(max_slew_time_ms),
27 max_slew_per_sample_(1000.0 / (max_slew_time_ms_ * sample_rate_)) { 28 max_slew_per_sample_(1000.0 / (max_slew_time_ms_ * sample_rate_)) {}
28 LOG(INFO) << "Creating a slew volume: " << max_slew_time_ms;
29 }
30 29
31 void SlewVolume::SetSampleRate(int sample_rate) { 30 void SlewVolume::SetSampleRate(int sample_rate) {
32 sample_rate_ = sample_rate; 31 sample_rate_ = sample_rate;
33 SetVolume(volume_scale_); 32 SetVolume(volume_scale_);
34 } 33 }
35 34
36 // Slew rate should be volume_to_slew / slew_time / sample_rate 35 // Slew rate should be volume_to_slew / slew_time / sample_rate
37 void SlewVolume::SetVolume(double volume_scale) { 36 void SlewVolume::SetVolume(double volume_scale) {
38 volume_scale_ = volume_scale; 37 volume_scale_ = volume_scale;
39 if (interrupted_) { 38 if (interrupted_) {
40 current_volume_ = volume_scale_; 39 current_volume_ = volume_scale_;
41 } 40 }
42 if (volume_scale_ > current_volume_) { 41 if (volume_scale_ > current_volume_) {
43 max_slew_per_sample_ = (volume_scale_ - current_volume_) * 1000.0 / 42 max_slew_per_sample_ = (volume_scale_ - current_volume_) * 1000.0 /
44 (max_slew_time_ms_ * sample_rate_); 43 (max_slew_time_ms_ * sample_rate_);
45 } else { 44 } else {
46 max_slew_per_sample_ = (current_volume_ - volume_scale_) * 1000.0 / 45 max_slew_per_sample_ = (current_volume_ - volume_scale_) * 1000.0 /
47 (max_slew_time_ms_ * sample_rate_); 46 (max_slew_time_ms_ * sample_rate_);
48 } 47 }
49 } 48 }
50 49
51 void SlewVolume::SetMaxSlewTimeMs(int max_slew_time_ms) { 50 void SlewVolume::SetMaxSlewTimeMs(int max_slew_time_ms) {
51 DCHECK_GE(max_slew_time_ms, 0);
52
52 max_slew_time_ms_ = max_slew_time_ms; 53 max_slew_time_ms_ = max_slew_time_ms;
53 } 54 }
54 55
55 void SlewVolume::Interrupted() { 56 void SlewVolume::Interrupted() {
56 interrupted_ = true; 57 interrupted_ = true;
57 current_volume_ = volume_scale_; 58 current_volume_ = volume_scale_;
58 } 59 }
59 60
60 void SlewVolume::ProcessFMAC(bool repeat_transition, 61 void SlewVolume::ProcessFMAC(bool repeat_transition,
61 const float* src, 62 const float* src,
(...skipping 17 matching lines...) Expand all
79 } else { 80 } else {
80 last_starting_volume_ = current_volume_; 81 last_starting_volume_ = current_volume_;
81 } 82 }
82 83
83 if (current_volume_ == volume_scale_) { 84 if (current_volume_ == volume_scale_) {
84 if (current_volume_ == 0.0) { 85 if (current_volume_ == 0.0) {
85 return; 86 return;
86 } 87 }
87 ::media::vector_math::FMAC(src, current_volume_, frames, dest); 88 ::media::vector_math::FMAC(src, current_volume_, frames, dest);
88 return; 89 return;
89 } else if (current_volume_ < volume_scale_) { 90 }
91
92 int original_frames = frames;
93 if (current_volume_ < volume_scale_) {
90 do { 94 do {
91 (*dest) += (*src) * current_volume_; 95 (*dest) += (*src) * current_volume_;
92 ++src; 96 ++src;
93 ++dest; 97 ++dest;
94 --frames; 98 --frames;
95 current_volume_ += max_slew_per_sample_; 99 current_volume_ += max_slew_per_sample_;
96 } while (current_volume_ < volume_scale_ && frames); 100 } while (current_volume_ < volume_scale_ && frames);
97 current_volume_ = std::min(current_volume_, volume_scale_); 101 current_volume_ = std::min(current_volume_, volume_scale_);
98 } else { // current_volume_ > volume_scale_ 102 } else { // current_volume_ > volume_scale_
99 do { 103 do {
100 (*dest) += (*src) * current_volume_; 104 (*dest) += (*src) * current_volume_;
101 ++src; 105 ++src;
102 ++dest; 106 ++dest;
103 --frames; 107 --frames;
104 current_volume_ -= max_slew_per_sample_; 108 current_volume_ -= max_slew_per_sample_;
105 } while (current_volume_ > volume_scale_ && frames); 109 } while (current_volume_ > volume_scale_ && frames);
106 current_volume_ = std::max(current_volume_, volume_scale_); 110 current_volume_ = std::max(current_volume_, volume_scale_);
107 } 111 }
108 112
113 while (frames && ((original_frames - frames) % 4) != 0) {
bcf 2017/05/03 06:14:07 I think this would be more explict as: while (fra
bshaya 2017/05/03 16:51:56 Done.
bcf 2017/05/03 18:07:09 This LGTM, but FYI the compiler will realize kRequ
bshaya 2017/05/04 03:01:18 That's fine. This is the same code that vector_mat
114 (*dest) += (*src) * current_volume_;
115 ++src;
116 ++dest;
117 --frames;
118 }
109 if (frames) { 119 if (frames) {
110 for (int f = 0; f < frames; ++f) { 120 ::media::vector_math::FMAC(src, current_volume_, frames, dest);
111 dest[f] += src[f] * current_volume_;
112 }
113 } 121 }
114 } 122 }
115 123
124 void SlewVolume::ProcessFMUL(bool repeat_transition,
125 const float* src,
126 int frames,
127 float* dest) {
128 DCHECK(src);
129 DCHECK(dest);
130 // Ensure |src| and |dest| are 16-byte aligned.
131 DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(src) &
132 (::media::vector_math::kRequiredAlignment - 1));
133 DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(dest) &
134 (::media::vector_math::kRequiredAlignment - 1));
135
136 if (!frames) {
137 return;
138 }
139
140 interrupted_ = false;
141 if (repeat_transition) {
142 current_volume_ = last_starting_volume_;
143 } else {
144 last_starting_volume_ = current_volume_;
145 }
146
147 if (current_volume_ == volume_scale_) {
148 if (current_volume_ == 0.0) {
149 memset(dest, 0, frames * sizeof(*dest));
bcf 2017/05/03 06:14:07 return after this?
bshaya 2017/05/03 16:51:56 Done.
150 }
151 ::media::vector_math::FMUL(src, current_volume_, frames, dest);
152 return;
153 }
154
155 int original_frames = frames;
156 if (current_volume_ < volume_scale_) {
157 do {
158 (*dest) = (*src) * current_volume_;
159 ++src;
160 ++dest;
161 --frames;
162 current_volume_ += max_slew_per_sample_;
163 } while (current_volume_ < volume_scale_ && frames);
164 current_volume_ = std::min(current_volume_, volume_scale_);
165 } else { // current_volume_ > volume_scale_
166 do {
167 (*dest) = (*src) * current_volume_;
168 ++src;
169 ++dest;
170 --frames;
171 current_volume_ -= max_slew_per_sample_;
172 } while (current_volume_ > volume_scale_ && frames);
173 current_volume_ = std::max(current_volume_, volume_scale_);
174 }
175
176 // Re-align to 16 bytes.
177 while (frames && ((original_frames - frames) % 4) != 0) {
bcf 2017/05/03 06:14:07 ditto. Also the statement becomes self documenting
bshaya 2017/05/03 16:51:56 Done.
178 (*dest) = (*src) * current_volume_;
179 ++src;
180 ++dest;
181 --frames;
182 }
183 if (frames) {
184 ::media::vector_math::FMUL(src, current_volume_, frames, dest);
185 }
186 }
187
116 // Scaling samples naively like this takes 0.2% of the CPU's time @ 44100hz 188 // Scaling samples naively like this takes 0.2% of the CPU's time @ 44100hz
117 // on pineapple. 189 // on pineapple.
118 // Assumes 2 channel audio. 190 // Assumes 2 channel audio.
119 bool SlewVolume::ProcessInterleaved(int32_t* data, int frames) { 191 bool SlewVolume::ProcessInterleaved(int32_t* data, int frames) {
120 DCHECK(data); 192 DCHECK(data);
121 193
122 if (!frames) { 194 if (!frames) {
123 return true; 195 return true;
124 } 196 }
125 197
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 } 236 }
165 237
166 for (int i = 0; i < 2 * frames; ++i) { 238 for (int i = 0; i < 2 * frames; ++i) {
167 data[i] *= current_volume_; 239 data[i] *= current_volume_;
168 } 240 }
169 return true; 241 return true;
170 } 242 }
171 243
172 } // namespace media 244 } // namespace media
173 } // namespace chromecast 245 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698