blob: ae45a45baa526ad9ce836ecf9077059d65100f84 [file] [log] [blame]
andrew@webrtc.org382c0c22014-05-05 18:22:21 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
12#define MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
andrew@webrtc.org21299d42014-05-14 19:00:59 +000013
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020014#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/array_view.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020016#include "typedefs.h" // NOLINT(build/include)
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000017
18namespace 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
henrik.lundin50499422016-11-29 04:26:24 -080026// Analyze(). When enough chunks have been accumulated to form a packet, call
27// Average() to get the audio level indicator for the RTP header.
28class RmsLevel {
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000029 public:
henrik.lundin50499422016-11-29 04:26:24 -080030 struct Levels {
31 int average;
32 int peak;
33 };
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000034
henrik.lundin290d43a2016-11-29 08:09:09 -080035 static constexpr int kMinLevelDb = 127;
36
henrik.lundin50499422016-11-29 04:26:24 -080037 RmsLevel();
38 ~RmsLevel();
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000039
40 // Can be called to reset internal states, but is not required during normal
41 // operation.
42 void Reset();
43
henrik.lundin50499422016-11-29 04:26:24 -080044 // Pass each chunk of audio to Analyze() to accumulate the level.
45 void Analyze(rtc::ArrayView<const int16_t> data);
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000046
47 // If all samples with the given |length| have a magnitude of zero, this is
48 // a shortcut to avoid some computation.
henrik.lundin50499422016-11-29 04:26:24 -080049 void AnalyzeMuted(size_t length);
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000050
henrik.lundin50499422016-11-29 04:26:24 -080051 // 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();
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000060
61 private:
henrik.lundin50499422016-11-29 04:26:24 -080062 // 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
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000066 float sum_square_;
Peter Kastingdce40cf2015-08-24 14:52:23 -070067 size_t sample_count_;
henrik.lundin50499422016-11-29 04:26:24 -080068 float max_sum_square_;
Danil Chapovalovdb9f7ab2018-06-19 10:50:11 +020069 absl::optional<size_t> block_size_;
andrew@webrtc.org382c0c22014-05-05 18:22:21 +000070};
71
72} // namespace webrtc
andrew@webrtc.org21299d42014-05-14 19:00:59 +000073
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020074#endif // MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_