audio_level.h (2975B)
1 /* 2 * Copyright (c) 2011 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 AUDIO_AUDIO_LEVEL_H_ 12 #define AUDIO_AUDIO_LEVEL_H_ 13 14 #include <cstdint> 15 16 #include "rtc_base/synchronization/mutex.h" 17 #include "rtc_base/thread_annotations.h" 18 19 namespace webrtc { 20 21 class AudioFrame; 22 namespace voe { 23 24 // This class is thread-safe. However, TotalEnergy() and TotalDuration() are 25 // related, so if you call ComputeLevel() on a different thread than you read 26 // these values, you still need to use lock to read them as a pair. 27 class AudioLevel { 28 public: 29 AudioLevel(); 30 ~AudioLevel(); 31 void Reset(); 32 33 // Returns the current audio level linearly [0,32767], which gets updated 34 // every "kUpdateFrequency+1" call to ComputeLevel() based on the maximum 35 // audio level of any audio frame, decaying by a factor of 1/4 each time 36 // LevelFullRange() gets updated. 37 // Called on "API thread(s)" from APIs like VoEBase::CreateChannel(), 38 // VoEBase::StopSend(). 39 int16_t LevelFullRange() const; 40 void ResetLevelFullRange(); 41 // See the description for "totalAudioEnergy" in the WebRTC stats spec 42 // (https://w3c.github.io/webrtc-stats/#dom-rtcaudiohandlerstats-totalaudioenergy) 43 // In our implementation, the total audio energy increases by the 44 // energy-equivalent of LevelFullRange() at the time of ComputeLevel(), rather 45 // than the energy of the samples in that specific audio frame. As a result, 46 // we may report a higher audio energy and audio level than the spec mandates. 47 // TODO(https://crbug.com/webrtc/10784): We should either do what the spec 48 // says or update the spec to match our implementation. If we want to have a 49 // decaying audio level we should probably update both the spec and the 50 // implementation to reduce the complexity of the definition. If we want to 51 // continue to have decaying audio we should have unittests covering the 52 // behavior of the decay. 53 double TotalEnergy() const; 54 double TotalDuration() const; 55 56 // Called on a native capture audio thread (platform dependent) from the 57 // AudioTransport::RecordedDataIsAvailable() callback. 58 // In Chrome, this method is called on the AudioInputDevice thread. 59 void ComputeLevel(const AudioFrame& audioFrame, double duration); 60 61 private: 62 enum { kUpdateFrequency = 10 }; 63 64 mutable Mutex mutex_; 65 66 int16_t abs_max_ RTC_GUARDED_BY(mutex_); 67 int16_t count_ RTC_GUARDED_BY(mutex_); 68 int16_t current_level_full_range_ RTC_GUARDED_BY(mutex_); 69 70 double total_energy_ RTC_GUARDED_BY(mutex_) = 0.0; 71 double total_duration_ RTC_GUARDED_BY(mutex_) = 0.0; 72 }; 73 74 } // namespace voe 75 } // namespace webrtc 76 77 #endif // AUDIO_AUDIO_LEVEL_H_