OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/renderer/media/media_stream_audio_level_calculator.h" | 5 #include "content/renderer/media/media_stream_audio_level_calculator.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
| 8 #include <limits> |
8 | 9 |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
11 #include "media/base/audio_bus.h" | 12 #include "media/base/audio_bus.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // Calculates the maximum absolute amplitude of the audio data. | 18 // Calculates the maximum absolute amplitude of the audio data. |
18 float MaxAmplitude(const float* audio_data, int length) { | 19 float MaxAmplitude(const float* audio_data, int length) { |
19 float max = 0.0f; | 20 float max = 0.0f; |
20 for (int i = 0; i < length; ++i) { | 21 for (int i = 0; i < length; ++i) { |
21 const float absolute = fabsf(audio_data[i]); | 22 const float absolute = fabsf(audio_data[i]); |
22 if (absolute > max) | 23 if (absolute > max) |
23 max = absolute; | 24 max = absolute; |
24 } | 25 } |
25 DCHECK(std::isfinite(max)); | 26 DCHECK(std::isfinite(max)); |
26 return max; | 27 return max; |
27 } | 28 } |
28 | 29 |
29 } // namespace | 30 } // namespace |
30 | 31 |
31 MediaStreamAudioLevelCalculator::MediaStreamAudioLevelCalculator() | 32 MediaStreamAudioLevelCalculator::Level::Level() : level_(0.0f) {} |
32 : counter_(0), | 33 |
33 max_amplitude_(0.0f), | 34 MediaStreamAudioLevelCalculator::Level::~Level() {} |
34 level_(0.0f) { | 35 |
| 36 float MediaStreamAudioLevelCalculator::Level::GetCurrent() const { |
| 37 base::AutoLock auto_lock(lock_); |
| 38 return level_; |
35 } | 39 } |
36 | 40 |
37 MediaStreamAudioLevelCalculator::~MediaStreamAudioLevelCalculator() { | 41 void MediaStreamAudioLevelCalculator::Level::Set(float level) { |
| 42 base::AutoLock auto_lock(lock_); |
| 43 level_ = level; |
38 } | 44 } |
39 | 45 |
40 float MediaStreamAudioLevelCalculator::Calculate( | 46 MediaStreamAudioLevelCalculator::MediaStreamAudioLevelCalculator() |
41 const media::AudioBus& audio_bus) { | 47 : counter_(0), max_amplitude_(0.0f), level_(new Level()) {} |
42 DCHECK(thread_checker_.CalledOnValidThread()); | 48 |
| 49 MediaStreamAudioLevelCalculator::~MediaStreamAudioLevelCalculator() { |
| 50 level_->Set(0.0f); |
| 51 } |
| 52 |
| 53 void MediaStreamAudioLevelCalculator::Calculate( |
| 54 const media::AudioBus& audio_bus, |
| 55 bool assume_nonzero_energy) { |
43 // |level_| is updated every 10 callbacks. For the case where callback comes | 56 // |level_| is updated every 10 callbacks. For the case where callback comes |
44 // every 10ms, |level_| will be updated approximately every 100ms. | 57 // every 10ms, |level_| will be updated approximately every 100ms. |
45 static const int kUpdateFrequency = 10; | 58 static const int kUpdateFrequency = 10; |
46 | 59 |
47 float max = 0.0f; | 60 float max = |
| 61 assume_nonzero_energy ? 1.0f / std::numeric_limits<int16_t>::max() : 0.0f; |
48 for (int i = 0; i < audio_bus.channels(); ++i) { | 62 for (int i = 0; i < audio_bus.channels(); ++i) { |
49 const float max_this_channel = | 63 const float max_this_channel = |
50 MaxAmplitude(audio_bus.channel(i), audio_bus.frames()); | 64 MaxAmplitude(audio_bus.channel(i), audio_bus.frames()); |
51 if (max_this_channel > max) | 65 if (max_this_channel > max) |
52 max = max_this_channel; | 66 max = max_this_channel; |
53 } | 67 } |
54 max_amplitude_ = std::max(max_amplitude_, max); | 68 max_amplitude_ = std::max(max_amplitude_, max); |
55 | 69 |
56 if (counter_++ == kUpdateFrequency) { | 70 if (counter_++ == kUpdateFrequency) { |
57 level_ = max_amplitude_; | 71 // Clip the exposed signal level to make sure it is in the range [0.0,1.0]. |
| 72 level_->Set(std::min(1.0f, max_amplitude_)); |
58 | 73 |
59 // Decay the absolute maximum amplitude by 1/4. | 74 // Decay the absolute maximum amplitude by 1/4. |
60 max_amplitude_ /= 4.0f; | 75 max_amplitude_ /= 4.0f; |
61 | 76 |
62 // Reset the counter. | 77 // Reset the counter. |
63 counter_ = 0; | 78 counter_ = 0; |
64 } | 79 } |
65 | |
66 return level_; | |
67 } | 80 } |
68 | 81 |
69 } // namespace content | 82 } // namespace content |
OLD | NEW |