diff --git a/webrtc/voice_engine/audio_level.cc b/webrtc/voice_engine/audio_level.cc index 27a7dde1b2..ab4114987c 100644 --- a/webrtc/voice_engine/audio_level.cc +++ b/webrtc/voice_engine/audio_level.cc @@ -48,7 +48,17 @@ void AudioLevel::Clear() { current_level_full_range_ = 0; } -void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) { +double AudioLevel::TotalEnergy() const { + rtc::CritScope cs(&crit_sect_); + return total_energy_; +} + +double AudioLevel::TotalDuration() const { + rtc::CritScope cs(&crit_sect_); + return total_duration_; +} + +void AudioLevel::ComputeLevel(const AudioFrame& audioFrame, double duration) { // Check speech level (works for 2 channels as well) int16_t abs_value = audioFrame.muted() ? 0 : WebRtcSpl_MaxAbsValueW16( @@ -83,6 +93,18 @@ void AudioLevel::ComputeLevel(const AudioFrame& audioFrame) { // Decay the absolute maximum (divide by 4) abs_max_ >>= 2; } + + // See the description for "totalAudioEnergy" in the WebRTC stats spec + // (https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy) + // for an explanation of these formulas. In short, we need a value that can + // be used to compute RMS audio levels over different time intervals, by + // taking the difference between the results from two getStats calls. To do + // this, the value needs to be of units "squared sample value * time". + double additional_energy = + static_cast(current_level_full_range_) / INT16_MAX; + additional_energy *= additional_energy; + total_energy_ += additional_energy * duration; + total_duration_ += duration; } } // namespace voe diff --git a/webrtc/voice_engine/audio_level.h b/webrtc/voice_engine/audio_level.h index 3bcb0d9b45..caecf40689 100644 --- a/webrtc/voice_engine/audio_level.h +++ b/webrtc/voice_engine/audio_level.h @@ -29,11 +29,15 @@ class AudioLevel { int8_t Level() const; int16_t LevelFullRange() const; void Clear(); + // See the description for "totalAudioEnergy" in the WebRTC stats spec + // (https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy) + double TotalEnergy() const; + double TotalDuration() const; // Called on a native capture audio thread (platform dependent) from the // AudioTransport::RecordedDataIsAvailable() callback. // In Chrome, this method is called on the AudioInputDevice thread. - void ComputeLevel(const AudioFrame& audioFrame); + void ComputeLevel(const AudioFrame& audioFrame, double duration); private: enum { kUpdateFrequency = 10 }; @@ -44,6 +48,9 @@ class AudioLevel { int16_t count_; int8_t current_level_; int16_t current_level_full_range_; + + double total_energy_ = 0.0; + double total_duration_ = 0.0; }; } // namespace voe diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 02001bac6b..5c2525cf2b 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -697,20 +697,9 @@ MixerParticipant::AudioFrameInfo Channel::GetAudioFrameWithMuted( // Measure audio level (0-9) // TODO(henrik.lundin) Use the |muted| information here too. - // TODO(deadbeef): Use RmsLevel for |_outputAudioLevel| as well (see + // TODO(deadbeef): Use RmsLevel for |_outputAudioLevel| (see // https://crbug.com/webrtc/7517). - _outputAudioLevel.ComputeLevel(*audioFrame); - // See the description for "totalAudioEnergy" in the WebRTC stats spec - // (https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy) - // for an explanation of these formulas. In short, we need a value that can - // be used to compute RMS audio levels over different time intervals, by - // taking the difference between the results from two getStats calls. To do - // this, the value needs to be of units "squared sample value * time". - double additional_energy = - static_cast(_outputAudioLevel.LevelFullRange()) / INT16_MAX; - additional_energy *= additional_energy; - totalOutputEnergy_ += additional_energy * kAudioSampleDurationSeconds; - totalOutputDuration_ += kAudioSampleDurationSeconds; + _outputAudioLevel.ComputeLevel(*audioFrame, kAudioSampleDurationSeconds); if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) { // The first frame with a valid rtp timestamp. @@ -2385,11 +2374,11 @@ int Channel::GetSpeechOutputLevelFullRange() const { } double Channel::GetTotalOutputEnergy() const { - return totalOutputEnergy_; + return _outputAudioLevel.TotalEnergy(); } double Channel::GetTotalOutputDuration() const { - return totalOutputDuration_; + return _outputAudioLevel.TotalDuration(); } void Channel::SetInputMute(bool enable) { diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 7fb8ae8b3c..9ec3eba922 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -474,8 +474,6 @@ class Channel acm2::RentACodec rent_a_codec_; std::unique_ptr audio_sink_; AudioLevel _outputAudioLevel; - double totalOutputEnergy_ = 0.0; - double totalOutputDuration_ = 0.0; bool _externalTransport; // Downsamples to the codec rate if necessary. PushResampler input_resampler_; diff --git a/webrtc/voice_engine/transmit_mixer.cc b/webrtc/voice_engine/transmit_mixer.cc index 06f37c2798..32f48482c0 100644 --- a/webrtc/voice_engine/transmit_mixer.cc +++ b/webrtc/voice_engine/transmit_mixer.cc @@ -313,20 +313,8 @@ TransmitMixer::PrepareDemux(const void* audioSamples, } // --- Measure audio level of speech after all processing. - _audioLevel.ComputeLevel(_audioFrame); - - // See the description for "totalAudioEnergy" in the WebRTC stats spec - // (https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy) - // for an explanation of these formulas. In short, we need a value that can - // be used to compute RMS audio levels over different time intervals, by - // taking the difference between the results from two getStats calls. To do - // this, the value needs to be of units "squared sample value * time". - double additional_energy = - static_cast(_audioLevel.LevelFullRange()) / INT16_MAX; - additional_energy *= additional_energy; double sample_duration = static_cast(nSamples) / samplesPerSec; - totalInputEnergy_ += additional_energy * sample_duration; - totalInputDuration_ += sample_duration; + _audioLevel.ComputeLevel(_audioFrame, sample_duration); return 0; } @@ -872,11 +860,11 @@ int16_t TransmitMixer::AudioLevelFullRange() const } double TransmitMixer::GetTotalInputEnergy() const { - return totalInputEnergy_; + return _audioLevel.TotalEnergy(); } double TransmitMixer::GetTotalInputDuration() const { - return totalInputDuration_; + return _audioLevel.TotalDuration(); } bool TransmitMixer::IsRecordingCall() diff --git a/webrtc/voice_engine/transmit_mixer.h b/webrtc/voice_engine/transmit_mixer.h index 6fcb86ea6f..0ba99cf9d8 100644 --- a/webrtc/voice_engine/transmit_mixer.h +++ b/webrtc/voice_engine/transmit_mixer.h @@ -197,8 +197,6 @@ private: bool _fileRecording = false; bool _fileCallRecording = false; voe::AudioLevel _audioLevel; - double totalInputEnergy_ = 0.0; - double totalInputDuration_ = 0.0; // protect file instances and their variables in MixedParticipants() rtc::CriticalSection _critSect; rtc::CriticalSection _callbackCritSect;