1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_HISTOGRAM_H_
12 #define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_HISTOGRAM_H_
13 
14 #include <string.h>
15 
16 #include "webrtc/base/scoped_ptr.h"
17 #include "webrtc/typedefs.h"
18 
19 namespace webrtc {
20 
21 // This class implements the histogram of loudness with circular buffers so that
22 // the histogram tracks the last T seconds of the loudness.
23 class Histogram {
24  public:
25   // Create a non-sliding Histogram.
26   static Histogram* Create();
27 
28   // Create a sliding Histogram, i.e. the histogram represents the last
29   // |window_size| samples.
30   static Histogram* Create(int window_size);
31   ~Histogram();
32 
33   // Insert RMS and the corresponding activity probability.
34   void Update(double rms, double activity_probability);
35 
36   // Reset the histogram, forget the past.
37   void Reset();
38 
39   // Current loudness, which is actually the mean of histogram in loudness
40   // domain.
41   double CurrentRms() const;
42 
43   // Sum of the histogram content.
44   double AudioContent() const;
45 
46   // Number of times the histogram has been updated.
num_updates()47   int num_updates() const { return num_updates_; }
48 
49  private:
50   Histogram();
51   explicit Histogram(int window);
52 
53   // Find the histogram bin associated with the given |rms|.
54   int GetBinIndex(double rms);
55 
56   void RemoveOldestEntryAndUpdate();
57   void InsertNewestEntryAndUpdate(int activity_prob_q10, int hist_index);
58   void UpdateHist(int activity_prob_q10, int hist_index);
59   void RemoveTransient();
60 
61   // Number of histogram bins.
62   static const int kHistSize = 77;
63 
64   // Number of times the histogram is updated
65   int num_updates_;
66   // Audio content, this should be equal to the sum of the components of
67   // |bin_count_q10_|.
68   int64_t audio_content_q10_;
69 
70   // Histogram of input RMS in Q10 with |kHistSize_| bins. In each 'Update(),'
71   // we increment the associated histogram-bin with the given probability. The
72   // increment is implemented in Q10 to avoid rounding errors.
73   int64_t bin_count_q10_[kHistSize];
74 
75   // Circular buffer for probabilities
76   rtc::scoped_ptr<int[]> activity_probability_;
77   // Circular buffer for histogram-indices of probabilities.
78   rtc::scoped_ptr<int[]> hist_bin_index_;
79   // Current index of circular buffer, where the newest data will be written to,
80   // therefore, pointing to the oldest data if buffer is full.
81   int buffer_index_;
82   // Indicating if buffer is full and we had a wrap around.
83   int buffer_is_full_;
84   // Size of circular buffer.
85   int len_circular_buffer_;
86   int len_high_activity_;
87 };
88 
89 }  // namespace webrtc
90 
91 #endif  // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_HISTOGRAM_H_
92