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 |
| 32 MediaStreamAudioLevelCalculator::ReportedLevel::ReportedLevel() |
| 33 : level_(0.0f) {} |
| 34 |
| 35 MediaStreamAudioLevelCalculator::ReportedLevel::~ReportedLevel() {} |
| 36 |
| 37 float MediaStreamAudioLevelCalculator::ReportedLevel::Get() const { |
| 38 base::AutoLock auto_lock(lock_); |
| 39 return level_; |
| 40 } |
| 41 |
31 MediaStreamAudioLevelCalculator::MediaStreamAudioLevelCalculator() | 42 MediaStreamAudioLevelCalculator::MediaStreamAudioLevelCalculator() |
32 : counter_(0), | 43 : counter_(0), |
33 max_amplitude_(0.0f), | 44 max_amplitude_(0.0f), |
34 level_(0.0f) { | 45 reported_level_(new ReportedLevel()) { |
35 } | 46 } |
36 | 47 |
37 MediaStreamAudioLevelCalculator::~MediaStreamAudioLevelCalculator() { | 48 MediaStreamAudioLevelCalculator::~MediaStreamAudioLevelCalculator() { |
| 49 base::AutoLock auto_lock(reported_level_->lock_); |
| 50 reported_level_->level_ = 0.0f; |
38 } | 51 } |
39 | 52 |
40 float MediaStreamAudioLevelCalculator::Calculate( | 53 void MediaStreamAudioLevelCalculator::Calculate( |
41 const media::AudioBus& audio_bus) { | 54 const media::AudioBus& audio_bus, |
| 55 bool assume_nonzero_energy) { |
42 DCHECK(thread_checker_.CalledOnValidThread()); | 56 DCHECK(thread_checker_.CalledOnValidThread()); |
43 // |level_| is updated every 10 callbacks. For the case where callback comes | 57 // |level_| is updated every 10 callbacks. For the case where callback comes |
44 // every 10ms, |level_| will be updated approximately every 100ms. | 58 // every 10ms, |level_| will be updated approximately every 100ms. |
45 static const int kUpdateFrequency = 10; | 59 static const int kUpdateFrequency = 10; |
46 | 60 |
47 float max = 0.0f; | 61 float max = assume_nonzero_energy ? 1.0f / std::numeric_limits<int16_t>::max() |
| 62 : 0.0f; |
48 for (int i = 0; i < audio_bus.channels(); ++i) { | 63 for (int i = 0; i < audio_bus.channels(); ++i) { |
49 const float max_this_channel = | 64 const float max_this_channel = |
50 MaxAmplitude(audio_bus.channel(i), audio_bus.frames()); | 65 MaxAmplitude(audio_bus.channel(i), audio_bus.frames()); |
51 if (max_this_channel > max) | 66 if (max_this_channel > max) |
52 max = max_this_channel; | 67 max = max_this_channel; |
53 } | 68 } |
54 max_amplitude_ = std::max(max_amplitude_, max); | 69 max_amplitude_ = std::max(max_amplitude_, max); |
55 | 70 |
56 if (counter_++ == kUpdateFrequency) { | 71 if (counter_++ == kUpdateFrequency) { |
57 level_ = max_amplitude_; | 72 { |
| 73 base::AutoLock auto_lock(reported_level_->lock_); |
| 74 // Clip the reported level to make sure it is in the range [0.0,1.0]. |
| 75 reported_level_->level_ = std::min(1.0f, max_amplitude_); |
| 76 } |
58 | 77 |
59 // Decay the absolute maximum amplitude by 1/4. | 78 // Decay the absolute maximum amplitude by 1/4. |
60 max_amplitude_ /= 4.0f; | 79 max_amplitude_ /= 4.0f; |
61 | 80 |
62 // Reset the counter. | 81 // Reset the counter. |
63 counter_ = 0; | 82 counter_ = 0; |
64 } | 83 } |
65 | |
66 return level_; | |
67 } | 84 } |
68 | 85 |
69 } // namespace content | 86 } // namespace content |
OLD | NEW |