• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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