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