Home | History | Annotate | Download | only in audio
      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.
     61   static float zero_power() { return -std::numeric_limits<float>::infinity(); }
     62 
     63   // dBFS value corresponding to maximum power in the audio signal.
     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