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

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

Issue 2341783004: [chromecast] Slew stream volume changes in StreamMixerAlsa. (Closed)
Patch Set: Created 4 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chromecast/media/cma/backend/alsa/slew_volume.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "media/base/vector_math.h"
11
12 namespace {
13
14 // The time to slew from 0.0 to 1.0.
15 const int kMaxSlewTimeMs = 100;
16 const int kDefaultSampleRate = 44100;
17 // ::media::base::FMAC requires |src| to be 16-byte aligned
18 const int kRequiredAlignment = 16;
19 }
20
21 namespace chromecast {
22 namespace media {
23
24 SlewVolume::SlewVolume() : SlewVolume(kMaxSlewTimeMs, kMaxSlewTimeMs) {}
25
26 SlewVolume::SlewVolume(int max_slew_time_up_ms, int max_slew_time_down_ms)
27 : max_slew_time_up_ms_(max_slew_time_up_ms),
28 max_slew_time_down_ms_(max_slew_time_down_ms),
29 max_slew_up_(1000.0 / (max_slew_time_up_ms * kDefaultSampleRate)),
30 max_slew_down_(1000.0 / (max_slew_time_down_ms * kDefaultSampleRate)) {}
31
32 // Slew rate should be 1 / (slew_time * sample_rate)
33 void SlewVolume::SetSampleRate(int sample_rate) {
34 max_slew_up_ = (1000.0 / (max_slew_time_up_ms_ * sample_rate));
35 max_slew_down_ = (1000.0 / (max_slew_time_down_ms_ * sample_rate));
36 }
37
38 void SlewVolume::SetVolume(double volume_scale) {
39 volume_scale_ = volume_scale;
40 }
41
42 bool SlewVolume::ProcessFMAC(const float* src, int frames, float* dest) {
kmackay 2016/09/14 20:48:15 Do we need to return bool? It always returns true
jyw 2016/09/15 01:12:15 Done.
43 DCHECK(src);
44 DCHECK(dest);
45 if (!frames) {
46 return true;
47 }
kmackay 2016/09/14 20:48:15 if (current_volume_ == volume_scale_) { ::media:
jyw 2016/09/15 01:12:15 Done.
48
49 if (current_volume_ < volume_scale_) {
50 do {
51 (*dest) += (*src) * current_volume_;
52 ++src;
53 ++dest;
54 --frames;
55 current_volume_ += max_slew_up_;
56 } while (current_volume_ < volume_scale_ && frames);
57 current_volume_ = std::min(current_volume_, volume_scale_);
58 } else {
59 do {
60 (*dest) += (*src) * current_volume_;
61 ++src;
62 ++dest;
63 --frames;
64 current_volume_ -= max_slew_down_;
65 } while (current_volume_ > volume_scale_ && frames);
66 current_volume_ = std::max(current_volume_, volume_scale_);
67 }
68
69 if (current_volume_ == 0.0) {
70 return true;
71 }
72
73 int unaligned_frames =
kmackay 2016/09/14 20:48:14 prefer to just do the simple naive method here rat
jyw 2016/09/15 01:12:15 Done.
74 (reinterpret_cast<uintptr_t>(src) & (kRequiredAlignment - 1)) /
75 sizeof(float);
76 if (unaligned_frames > 0) {
77 unaligned_frames = kRequiredAlignment / sizeof(float) - unaligned_frames;
78 }
79 if (frames >= unaligned_frames) {
80 for (int f = 0; f < unaligned_frames; ++f) {
81 (*dest) += (*src) * current_volume_;
82 ++src;
83 ++dest;
84 }
85 frames -= unaligned_frames;
86 }
87
88 if (frames) {
89 ::media::vector_math::FMAC(src, volume_scale_, frames, dest);
90 }
91 return true;
92 }
93
94 // Scaling samples naively like this takes 0.2% of the CPU's time @ 44100hz
95 // (profiled with waves_standalone).
96 // Assumes 2 channel audio.
97 bool SlewVolume::ProcessInterleaved(int32_t* data, int frames) {
98 DCHECK(data);
99
100 if (!frames) {
101 return true;
102 }
kmackay 2016/09/14 20:48:14 if (current_volume_ == volume_scale_) { ::media:
jyw 2016/09/15 01:12:15 can't use FMUL, which requires floats. data is an
103
104 if (current_volume_ < volume_scale_) {
105 do {
106 (*data) *= current_volume_;
kmackay 2016/09/14 20:48:14 It might be nice to have a helper function/macro f
107 ++data;
108 (*data) *= current_volume_;
109 ++data;
110 --frames;
111 current_volume_ += max_slew_up_;
112 } while (current_volume_ < volume_scale_ && frames);
113 current_volume_ = std::min(current_volume_, volume_scale_);
114 } else {
115 do {
116 (*data) *= current_volume_;
117 ++data;
118 (*data) *= current_volume_;
119 ++data;
120 --frames;
121 current_volume_ -= max_slew_down_;
122 } while (current_volume_ > volume_scale_ && frames);
123 current_volume_ = std::max(current_volume_, volume_scale_);
124 }
125
126 if (current_volume_ == 1.0) {
127 return true;
128 }
129
130 if (current_volume_ == 0.0) {
131 std::fill_n(data, frames * 2, 0);
132 return true;
133 }
134
135 while (frames) {
136 (*data) *= current_volume_;
137 ++data;
138 (*data) *= current_volume_;
139 ++data;
140 --frames;
141 }
142
143 return true;
144 }
145
146 } // namespace media
147 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698