1 /*
2  *  Copyright (c) 2014 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 MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
12 #define MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
13 
14 #include "api/array_view.h"
15 #include "api/optional.h"
16 #include "typedefs.h"  // NOLINT(build/include)
17 
18 namespace webrtc {
19 
20 // Computes the root mean square (RMS) level in dBFs (decibels from digital
21 // full-scale) of audio data. The computation follows RFC 6465:
22 // https://tools.ietf.org/html/rfc6465
23 // with the intent that it can provide the RTP audio level indication.
24 //
25 // The expected approach is to provide constant-sized chunks of audio to
26 // Analyze(). When enough chunks have been accumulated to form a packet, call
27 // Average() to get the audio level indicator for the RTP header.
28 class RmsLevel {
29  public:
30   struct Levels {
31     int average;
32     int peak;
33   };
34 
35   static constexpr int kMinLevelDb = 127;
36 
37   RmsLevel();
38   ~RmsLevel();
39 
40   // Can be called to reset internal states, but is not required during normal
41   // operation.
42   void Reset();
43 
44   // Pass each chunk of audio to Analyze() to accumulate the level.
45   void Analyze(rtc::ArrayView<const int16_t> data);
46 
47   // If all samples with the given |length| have a magnitude of zero, this is
48   // a shortcut to avoid some computation.
49   void AnalyzeMuted(size_t length);
50 
51   // Computes the RMS level over all data passed to Analyze() since the last
52   // call to Average(). The returned value is positive but should be interpreted
53   // as negative as per the RFC. It is constrained to [0, 127]. Resets the
54   // internal state to start a new measurement period.
55   int Average();
56 
57   // Like Average() above, but also returns the RMS peak value. Resets the
58   // internal state to start a new measurement period.
59   Levels AverageAndPeak();
60 
61  private:
62   // Compares |block_size| with |block_size_|. If they are different, calls
63   // Reset() and stores the new size.
64   void CheckBlockSize(size_t block_size);
65 
66   float sum_square_;
67   size_t sample_count_;
68   float max_sum_square_;
69   rtc::Optional<size_t> block_size_;
70 };
71 
72 }  // namespace webrtc
73 
74 #endif  // MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
75 
76