Revert of Move smoothing filter to common audio. (patchset #3 id:60001 of https://codereview.webrtc.org/2484153002/ )

Reason for revert:
Breaks downstream projects:
error: undefined reference to 'rtc::ExpFilter::kValueUndefined'
error: undefined reference to 'rtc::ExpFilter::Apply(float, float)'
error: undefined reference to 'rtc::ExpFilter::Reset(float)'
rror: undefined reference to 'rtc::ExpFilter::UpdateBase(float)'

Original issue's description:
> Move smoothing filter to common audio.
>
> This will make the smoothing filter a basic tool that is going to be used by both voice engine and ANA.
>
> BUG=webrtc:6443
>
> Committed: https://crrev.com/a82395bf7cd15b7396456df06fe952ede8db0c39
> Cr-Commit-Position: refs/heads/master@{#15146}

TBR=minyue@webrtc.org,solenberg@webrtc.org,perkj@webrtc.org,tommi@webrtc.org,michaelt@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6443

Review-Url: https://codereview.webrtc.org/2510373002
Cr-Commit-Position: refs/heads/master@{#15147}
This commit is contained in:
magjed
2016-11-18 01:31:16 -08:00
committed by Commit bot
parent a82395bf7c
commit d7ac0a9bcc
12 changed files with 23 additions and 26 deletions

View File

@ -757,6 +757,8 @@ rtc_static_library("audio_network_adaptor") {
"audio_network_adaptor/frame_length_controller.cc",
"audio_network_adaptor/frame_length_controller.h",
"audio_network_adaptor/include/audio_network_adaptor.h",
"audio_network_adaptor/smoothing_filter.cc",
"audio_network_adaptor/smoothing_filter.h",
]
deps = [

View File

@ -14,8 +14,8 @@
#include <memory>
#include "webrtc/base/constructormagic.h"
#include "webrtc/common_audio/smoothing_filter.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
namespace webrtc {

View File

@ -10,8 +10,8 @@
#include <utility>
#include "webrtc/common_audio/mocks/mock_smoothing_filter.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
@ -55,6 +55,7 @@ FecControllerStates CreateFecController(bool initial_fec_enabled) {
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
states.controller.reset(new FecController(
FecController::Config(
@ -261,6 +262,7 @@ TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) {
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
states.controller.reset(new FecController(
FecController::Config(
@ -291,6 +293,7 @@ TEST(FecControllerDeathTest, InvalidConfig) {
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
EXPECT_DEATH(
states.controller.reset(new FecController(

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_
#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_
#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
#include "webrtc/test/gmock.h"
namespace webrtc {
class MockSmoothingFilter : public SmoothingFilter {
public:
virtual ~MockSmoothingFilter() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD1(AddSample, void(float));
MOCK_CONST_METHOD0(GetAverage, rtc::Optional<float>());
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <cmath>
#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
namespace webrtc {
SmoothingFilterImpl::SmoothingFilterImpl(int time_constant_ms,
const Clock* clock)
: time_constant_ms_(time_constant_ms),
clock_(clock),
first_sample_received_(false),
initialized_(false),
first_sample_time_ms_(0),
last_sample_time_ms_(0),
filter_(0.0) {}
void SmoothingFilterImpl::AddSample(float sample) {
if (!first_sample_received_) {
last_sample_time_ms_ = first_sample_time_ms_ = clock_->TimeInMilliseconds();
first_sample_received_ = true;
RTC_DCHECK_EQ(rtc::ExpFilter::kValueUndefined, filter_.filtered());
// Since this is first sample, any value for argument 1 should work.
filter_.Apply(0.0f, sample);
return;
}
int64_t now_ms = clock_->TimeInMilliseconds();
if (!initialized_) {
float duration = now_ms - first_sample_time_ms_;
if (duration < static_cast<int64_t>(time_constant_ms_)) {
filter_.UpdateBase(exp(1.0f / duration));
} else {
initialized_ = true;
filter_.UpdateBase(exp(1.0f / time_constant_ms_));
}
}
// The filter will do the following:
// float alpha = pow(base, last_update_time_ms_ - now_ms);
// filtered_ = alpha * filtered_ + (1 - alpha) * sample;
filter_.Apply(static_cast<float>(last_sample_time_ms_ - now_ms), sample);
last_sample_time_ms_ = now_ms;
}
rtc::Optional<float> SmoothingFilterImpl::GetAverage() const {
float value = filter_.filtered();
return value == rtc::ExpFilter::kValueUndefined ? rtc::Optional<float>()
: rtc::Optional<float>(value);
}
} // namespace webrtc

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_
#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/exp_filter.h"
#include "webrtc/base/optional.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
class SmoothingFilter {
public:
virtual ~SmoothingFilter() = default;
virtual void AddSample(float sample) = 0;
virtual rtc::Optional<float> GetAverage() const = 0;
};
// SmoothingFilterImpl applies an exponential filter
// alpha = exp(-sample_interval / time_constant);
// y[t] = alpha * y[t-1] + (1 - alpha) * sample;
class SmoothingFilterImpl final : public SmoothingFilter {
public:
// |time_constant_ms| is the time constant for the exponential filter.
SmoothingFilterImpl(int time_constant_ms, const Clock* clock);
void AddSample(float sample) override;
rtc::Optional<float> GetAverage() const override;
private:
const int time_constant_ms_;
const Clock* const clock_;
bool first_sample_received_;
bool initialized_;
int64_t first_sample_time_ms_;
int64_t last_sample_time_ms_;
rtc::ExpFilter filter_;
RTC_DISALLOW_COPY_AND_ASSIGN(SmoothingFilterImpl);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
namespace {
constexpr int kTimeConstantMs = 1000;
constexpr float kMaxAbsError = 0.0001f;
constexpr int64_t kClockInitialTime = 123456;
struct SmoothingFilterStates {
std::unique_ptr<SimulatedClock> simulated_clock;
std::unique_ptr<SmoothingFilter> smoothing_filter;
};
SmoothingFilterStates CreateSmoothingFilter() {
SmoothingFilterStates states;
states.simulated_clock.reset(new SimulatedClock(kClockInitialTime));
states.smoothing_filter.reset(
new SmoothingFilterImpl(kTimeConstantMs, states.simulated_clock.get()));
return states;
}
void CheckOutput(SmoothingFilterStates* states,
int advance_time_ms,
float sample,
float expected_ouput) {
states->simulated_clock->AdvanceTimeMilliseconds(advance_time_ms);
states->smoothing_filter->AddSample(sample);
auto output = states->smoothing_filter->GetAverage();
EXPECT_TRUE(output);
EXPECT_NEAR(expected_ouput, *output, kMaxAbsError);
}
} // namespace
TEST(SmoothingFilterTest, NoOutputWhenNoSampleAdded) {
auto states = CreateSmoothingFilter();
EXPECT_FALSE(states.smoothing_filter->GetAverage());
}
// Python script to calculate the reference values used in this test.
// import math
//
// class ExpFilter:
// alpha = 0.0
// old_value = 0.0
// def calc(self, new_value):
// self.old_value = self.old_value * self.alpha
// + (1.0 - self.alpha) * new_value
// return self.old_value
//
// delta_t = 100.0
// filter = ExpFilter()
// total_t = 100.0
// filter.alpha = math.exp(-delta_t/ total_t)
// print filter.calc(1.0)
// total_t = 200.0
// filter.alpha = math.exp(-delta_t/ total_t)
// print filter.calc(0.0)
// total_t = 300.0
// filter.alpha = math.exp(-delta_t/ total_t)
// print filter.calc(1.0)
TEST(SmoothingFilterTest, CheckBehaviorBeforeInitialized) {
// Adding three samples, all added before |kTimeConstantMs| is reached.
constexpr int kTimeIntervalMs = 100;
auto states = CreateSmoothingFilter();
states.smoothing_filter->AddSample(0.0);
CheckOutput(&states, kTimeIntervalMs, 1.0, 0.63212f);
CheckOutput(&states, kTimeIntervalMs, 0.0, 0.38340f);
CheckOutput(&states, kTimeIntervalMs, 1.0, 0.55818f);
}
// Python script to calculate the reference value used in this test.
// (after defining ExpFilter as for CheckBehaviorBeforeInitialized)
// time_constant_ms = 1000.0
// filter = ExpFilter()
// delta_t = 1100.0
// filter.alpha = math.exp(-delta_t/ time_constant_ms)
// print filter.calc(1.0)
// delta_t = 100.0
// filter.alpha = math.exp(-delta_t/ time_constant_ms)
// print filter.calc(0.0)
// print filter.calc(1.0)
TEST(SmoothingFilterTest, CheckBehaviorAfterInitialized) {
constexpr int kTimeIntervalMs = 100;
auto states = CreateSmoothingFilter();
states.smoothing_filter->AddSample(0.0);
states.simulated_clock->AdvanceTimeMilliseconds(kTimeConstantMs);
CheckOutput(&states, kTimeIntervalMs, 1.0, 0.66713f);
CheckOutput(&states, kTimeIntervalMs, 0.0, 0.60364f);
CheckOutput(&states, kTimeIntervalMs, 1.0, 0.64136f);
}
} // namespace webrtc