1 // Copyright 2013 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 #ifndef MEDIA_AUDIO_AUDIO_POWER_MONITOR_H_ 6 #define MEDIA_AUDIO_AUDIO_POWER_MONITOR_H_ 7 8 #include <limits> 9 #include <utility> 10 11 #include "base/callback.h" 12 #include "base/synchronization/lock.h" 13 #include "media/base/media_export.h" 14 15 // An audio signal power monitor. It is periodically provided an AudioBus by 16 // the native audio thread, and the audio samples in each channel are analyzed 17 // to determine the average power of the signal over a time period. Here 18 // "average power" is a running average calculated by using a first-order 19 // low-pass filter over the square of the samples scanned. Whenever reporting 20 // the power level, this running average is converted to dBFS (decibels relative 21 // to full-scale) units. 22 // 23 // Note that extreme care has been taken to make the AudioPowerMonitor::Scan() 24 // method safe to be called on the native audio thread. The code acquires no 25 // locks, nor engages in any operation that could result in an 26 // undetermined/unbounded amount of run-time. 27 28 namespace base { 29 class TimeDelta; 30 } 31 32 namespace media { 33 34 class AudioBus; 35 36 class MEDIA_EXPORT AudioPowerMonitor { 37 public: 38 // |sample_rate| is the audio signal sample rate (Hz). |time_constant| 39 // characterizes how samples are averaged over time to determine the power 40 // level; and is the amount of time it takes a zero power level to increase to 41 // ~63.2% of maximum given a step input signal. 42 AudioPowerMonitor(int sample_rate, const base::TimeDelta& time_constant); 43 44 ~AudioPowerMonitor(); 45 46 // Reset power monitor to initial state (zero power level). This should not 47 // be called while another thread is scanning. 48 void Reset(); 49 50 // Scan more |frames| of audio data from |buffer|. It is safe to call this 51 // from a real-time priority thread. 52 void Scan(const AudioBus& buffer, int frames); 53 54 // Returns the current power level in dBFS and clip status. Clip status is 55 // true whenever any *one* sample scanned exceeded maximum amplitude since 56 // this method's last invocation. It is safe to call this method from any 57 // thread. 58 std::pair<float, bool> ReadCurrentPowerAndClip(); 59 60 // dBFS value corresponding to zero power in the audio signal. zero_power()61 static float zero_power() { return -std::numeric_limits<float>::infinity(); } 62 63 // dBFS value corresponding to maximum power in the audio signal. max_power()64 static float max_power() { return 0.0f; } 65 66 private: 67 // The weight applied when averaging-in each sample. Computed from the 68 // |sample_rate| and |time_constant|. 69 const float sample_weight_; 70 71 // Accumulated results over one or more calls to Scan(). These should only be 72 // touched by the thread invoking Scan(). 73 float average_power_; 74 bool has_clipped_; 75 76 // Copies of power and clip status, used to deliver results synchronously 77 // across threads. 78 base::Lock reading_lock_; 79 float power_reading_; 80 bool clipped_reading_; 81 82 DISALLOW_COPY_AND_ASSIGN(AudioPowerMonitor); 83 }; 84 85 } // namespace media 86 87 #endif // MEDIA_AUDIO_AUDIO_POWER_MONITOR_H_ 88