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