mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 06:40:43 +01:00

Just applied a short sed script. See bug description for the motiviation for this change. This is the command that was used to generate the changes: $ find . -type f \( -iname '*.cc' -o -iname '*.h' \) -print0 | \ xargs -0 sed -i -e 's/(const override)/(const, override)/' Bug: webrtc:13090 Change-Id: Iec7d280f9d55263a972dbb3bd644ebfcd2eb38cf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/249088 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Ali Tofigh <alito@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35801}
181 lines
6.9 KiB
C++
181 lines
6.9 KiB
C++
/*
|
|
* Copyright (c) 2018 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 "modules/audio_processing/agc2/vad_wrapper.h"
|
|
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <tuple>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "modules/audio_processing/agc2/agc2_common.h"
|
|
#include "modules/audio_processing/include/audio_frame_view.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/gunit.h"
|
|
#include "rtc_base/numerics/safe_compare.h"
|
|
#include "test/gmock.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
using ::testing::AnyNumber;
|
|
using ::testing::Return;
|
|
using ::testing::ReturnRoundRobin;
|
|
using ::testing::Truly;
|
|
|
|
constexpr int kNumFramesPerSecond = 100;
|
|
|
|
constexpr int kNoVadPeriodicReset =
|
|
kFrameDurationMs * (std::numeric_limits<int>::max() / kFrameDurationMs);
|
|
|
|
constexpr int kSampleRate8kHz = 8000;
|
|
|
|
class MockVad : public VoiceActivityDetectorWrapper::MonoVad {
|
|
public:
|
|
MOCK_METHOD(int, SampleRateHz, (), (const, override));
|
|
MOCK_METHOD(void, Reset, (), (override));
|
|
MOCK_METHOD(float, Analyze, (rtc::ArrayView<const float> frame), (override));
|
|
};
|
|
|
|
// Checks that the ctor and `Initialize()` read the sample rate of the wrapped
|
|
// VAD.
|
|
TEST(GainController2VoiceActivityDetectorWrapper, CtorAndInitReadSampleRate) {
|
|
auto vad = std::make_unique<MockVad>();
|
|
EXPECT_CALL(*vad, SampleRateHz)
|
|
.Times(2)
|
|
.WillRepeatedly(Return(kSampleRate8kHz));
|
|
EXPECT_CALL(*vad, Reset).Times(AnyNumber());
|
|
auto vad_wrapper = std::make_unique<VoiceActivityDetectorWrapper>(
|
|
kNoVadPeriodicReset, std::move(vad), kSampleRate8kHz);
|
|
}
|
|
|
|
// Creates a `VoiceActivityDetectorWrapper` injecting a mock VAD that
|
|
// repeatedly returns the next value from `speech_probabilities` and that
|
|
// restarts from the beginning when after the last element is returned.
|
|
std::unique_ptr<VoiceActivityDetectorWrapper> CreateMockVadWrapper(
|
|
int vad_reset_period_ms,
|
|
int sample_rate_hz,
|
|
const std::vector<float>& speech_probabilities,
|
|
int expected_vad_reset_calls) {
|
|
auto vad = std::make_unique<MockVad>();
|
|
EXPECT_CALL(*vad, SampleRateHz)
|
|
.Times(AnyNumber())
|
|
.WillRepeatedly(Return(sample_rate_hz));
|
|
if (expected_vad_reset_calls >= 0) {
|
|
EXPECT_CALL(*vad, Reset).Times(expected_vad_reset_calls);
|
|
}
|
|
EXPECT_CALL(*vad, Analyze)
|
|
.Times(AnyNumber())
|
|
.WillRepeatedly(ReturnRoundRobin(speech_probabilities));
|
|
return std::make_unique<VoiceActivityDetectorWrapper>(
|
|
vad_reset_period_ms, std::move(vad), kSampleRate8kHz);
|
|
}
|
|
|
|
// 10 ms mono frame.
|
|
struct FrameWithView {
|
|
// Ctor. Initializes the frame samples with `value`.
|
|
explicit FrameWithView(int sample_rate_hz)
|
|
: samples(rtc::CheckedDivExact(sample_rate_hz, kNumFramesPerSecond),
|
|
0.0f),
|
|
channel0(samples.data()),
|
|
view(&channel0, /*num_channels=*/1, samples.size()) {}
|
|
std::vector<float> samples;
|
|
const float* const channel0;
|
|
const AudioFrameView<const float> view;
|
|
};
|
|
|
|
// Checks that the expected speech probabilities are returned.
|
|
TEST(GainController2VoiceActivityDetectorWrapper, CheckSpeechProbabilities) {
|
|
const std::vector<float> speech_probabilities{0.709f, 0.484f, 0.882f, 0.167f,
|
|
0.44f, 0.525f, 0.858f, 0.314f,
|
|
0.653f, 0.965f, 0.413f, 0.0f};
|
|
auto vad_wrapper = CreateMockVadWrapper(kNoVadPeriodicReset, kSampleRate8kHz,
|
|
speech_probabilities,
|
|
/*expected_vad_reset_calls=*/1);
|
|
FrameWithView frame(kSampleRate8kHz);
|
|
for (int i = 0; rtc::SafeLt(i, speech_probabilities.size()); ++i) {
|
|
SCOPED_TRACE(i);
|
|
EXPECT_EQ(speech_probabilities[i], vad_wrapper->Analyze(frame.view));
|
|
}
|
|
}
|
|
|
|
// Checks that the VAD is not periodically reset.
|
|
TEST(GainController2VoiceActivityDetectorWrapper, VadNoPeriodicReset) {
|
|
constexpr int kNumFrames = 19;
|
|
auto vad_wrapper = CreateMockVadWrapper(kNoVadPeriodicReset, kSampleRate8kHz,
|
|
/*speech_probabilities=*/{1.0f},
|
|
/*expected_vad_reset_calls=*/1);
|
|
FrameWithView frame(kSampleRate8kHz);
|
|
for (int i = 0; i < kNumFrames; ++i) {
|
|
vad_wrapper->Analyze(frame.view);
|
|
}
|
|
}
|
|
|
|
class VadPeriodResetParametrization
|
|
: public ::testing::TestWithParam<std::tuple<int, int>> {
|
|
protected:
|
|
int num_frames() const { return std::get<0>(GetParam()); }
|
|
int vad_reset_period_frames() const { return std::get<1>(GetParam()); }
|
|
};
|
|
|
|
// Checks that the VAD is periodically reset with the expected period.
|
|
TEST_P(VadPeriodResetParametrization, VadPeriodicReset) {
|
|
auto vad_wrapper = CreateMockVadWrapper(
|
|
/*vad_reset_period_ms=*/vad_reset_period_frames() * kFrameDurationMs,
|
|
kSampleRate8kHz,
|
|
/*speech_probabilities=*/{1.0f},
|
|
/*expected_vad_reset_calls=*/1 +
|
|
num_frames() / vad_reset_period_frames());
|
|
FrameWithView frame(kSampleRate8kHz);
|
|
for (int i = 0; i < num_frames(); ++i) {
|
|
vad_wrapper->Analyze(frame.view);
|
|
}
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(GainController2VoiceActivityDetectorWrapper,
|
|
VadPeriodResetParametrization,
|
|
::testing::Combine(::testing::Values(1, 19, 123),
|
|
::testing::Values(2, 5, 20, 53)));
|
|
|
|
class VadResamplingParametrization
|
|
: public ::testing::TestWithParam<std::tuple<int, int>> {
|
|
protected:
|
|
int input_sample_rate_hz() const { return std::get<0>(GetParam()); }
|
|
int vad_sample_rate_hz() const { return std::get<1>(GetParam()); }
|
|
};
|
|
|
|
// Checks that regardless of the input audio sample rate, the wrapped VAD
|
|
// analyzes frames having the expected size, that is according to its internal
|
|
// sample rate.
|
|
TEST_P(VadResamplingParametrization, CheckResampledFrameSize) {
|
|
auto vad = std::make_unique<MockVad>();
|
|
EXPECT_CALL(*vad, SampleRateHz)
|
|
.Times(AnyNumber())
|
|
.WillRepeatedly(Return(vad_sample_rate_hz()));
|
|
EXPECT_CALL(*vad, Reset).Times(1);
|
|
EXPECT_CALL(*vad, Analyze(Truly([this](rtc::ArrayView<const float> frame) {
|
|
return rtc::SafeEq(frame.size(), rtc::CheckedDivExact(vad_sample_rate_hz(),
|
|
kNumFramesPerSecond));
|
|
}))).Times(1);
|
|
auto vad_wrapper = std::make_unique<VoiceActivityDetectorWrapper>(
|
|
kNoVadPeriodicReset, std::move(vad), input_sample_rate_hz());
|
|
FrameWithView frame(input_sample_rate_hz());
|
|
vad_wrapper->Analyze(frame.view);
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
GainController2VoiceActivityDetectorWrapper,
|
|
VadResamplingParametrization,
|
|
::testing::Combine(::testing::Values(8000, 16000, 44100, 48000),
|
|
::testing::Values(6000, 8000, 12000, 16000, 24000)));
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|