Move total audio energy and duration tracking to AudioLevel and protect with existing critial section.

BUG=webrtc:7982

Review-Url: https://codereview.webrtc.org/2984473002
Cr-Commit-Position: refs/heads/master@{#19105}
This commit is contained in:
zstein 2017-07-20 09:57:42 -07:00 committed by Commit Bot
parent c4a5c14e8a
commit 3c45186ef2
6 changed files with 38 additions and 36 deletions

View File

@ -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<double>(current_level_full_range_) / INT16_MAX;
additional_energy *= additional_energy;
total_energy_ += additional_energy * duration;
total_duration_ += duration;
}
} // namespace voe

View File

@ -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

View File

@ -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<double>(_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) {

View File

@ -474,8 +474,6 @@ class Channel
acm2::RentACodec rent_a_codec_;
std::unique_ptr<AudioSinkInterface> audio_sink_;
AudioLevel _outputAudioLevel;
double totalOutputEnergy_ = 0.0;
double totalOutputDuration_ = 0.0;
bool _externalTransport;
// Downsamples to the codec rate if necessary.
PushResampler<int16_t> input_resampler_;

View File

@ -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<double>(_audioLevel.LevelFullRange()) / INT16_MAX;
additional_energy *= additional_energy;
double sample_duration = static_cast<double>(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()

View File

@ -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;