Files
platform-external-webrtc/webrtc/modules/audio_coding/neteq/time_stretch_unittest.cc
Henrik Lundin cf808d2366 Add new fast mode for NetEq's Accelerate operation
This change instroduces a mode where the Accelerate operation will be
more aggressive. When enabled, it will allow acceleration at lower
correlation levels, and possibly remove multiple pitch periods at
once.

The feature is enabled through NetEq::Config, and is off by
default. This means that bit-exactness tests are currently not
affected.

A unit test was added for the Accelerate class, with and without fast
mode enabled.

BUG=4691
R=minyue@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/50039004

Cr-Commit-Position: refs/heads/master@{#9295}
2015-05-27 12:33:39 +00:00

128 lines
4.3 KiB
C++

/*
* Copyright (c) 2012 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.
*/
// Unit tests for Accelerate and PreemptiveExpand classes.
#include "webrtc/modules/audio_coding/neteq/accelerate.h"
#include "webrtc/modules/audio_coding/neteq/preemptive_expand.h"
#include <map>
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_coding/neteq/background_noise.h"
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
namespace {
const size_t kNumChannels = 1;
}
TEST(TimeStretch, CreateAndDestroy) {
const int kSampleRate = 8000;
const int kOverlapSamples = 5 * kSampleRate / 8000;
BackgroundNoise bgn(kNumChannels);
Accelerate accelerate(kSampleRate, kNumChannels, bgn);
PreemptiveExpand preemptive_expand(
kSampleRate, kNumChannels, bgn, kOverlapSamples);
}
TEST(TimeStretch, CreateUsingFactory) {
const int kSampleRate = 8000;
const int kOverlapSamples = 5 * kSampleRate / 8000;
BackgroundNoise bgn(kNumChannels);
AccelerateFactory accelerate_factory;
Accelerate* accelerate =
accelerate_factory.Create(kSampleRate, kNumChannels, bgn);
EXPECT_TRUE(accelerate != NULL);
delete accelerate;
PreemptiveExpandFactory preemptive_expand_factory;
PreemptiveExpand* preemptive_expand = preemptive_expand_factory.Create(
kSampleRate, kNumChannels, bgn, kOverlapSamples);
EXPECT_TRUE(preemptive_expand != NULL);
delete preemptive_expand;
}
class TimeStretchTest : public ::testing::Test {
protected:
TimeStretchTest()
: input_file_(new test::InputAudioFile(
test::ResourcePath("audio_coding/testfile32kHz", "pcm"))),
sample_rate_hz_(32000),
block_size_(30 * sample_rate_hz_ / 1000), // 30 ms
audio_(new int16_t[block_size_]),
background_noise_(kNumChannels) {
WebRtcSpl_Init();
}
const int16_t* Next30Ms() {
CHECK(input_file_->Read(block_size_, audio_.get()));
return audio_.get();
}
// Returns the total length change (in samples) that the accelerate operation
// resulted in during the run.
int TestAccelerate(int loops, bool fast_mode) {
Accelerate accelerate(sample_rate_hz_, kNumChannels, background_noise_);
int total_length_change = 0;
for (int i = 0; i < loops; ++i) {
AudioMultiVector output(kNumChannels);
int16_t length_change;
UpdateReturnStats(accelerate.Process(Next30Ms(), block_size_, fast_mode,
&output, &length_change));
total_length_change += length_change;
}
return total_length_change;
}
void UpdateReturnStats(TimeStretch::ReturnCodes ret) {
switch (ret) {
case TimeStretch::kSuccess:
case TimeStretch::kSuccessLowEnergy:
case TimeStretch::kNoStretch:
++return_stats_[ret];
break;
case TimeStretch::kError:
FAIL() << "Process returned an error";
}
}
rtc::scoped_ptr<test::InputAudioFile> input_file_;
const int sample_rate_hz_;
const size_t block_size_;
rtc::scoped_ptr<int16_t[]> audio_;
std::map<TimeStretch::ReturnCodes, int> return_stats_;
BackgroundNoise background_noise_;
};
TEST_F(TimeStretchTest, Accelerate) {
// TestAccelerate returns the total length change in samples.
EXPECT_EQ(15268, TestAccelerate(100, false));
EXPECT_EQ(9, return_stats_[TimeStretch::kSuccess]);
EXPECT_EQ(58, return_stats_[TimeStretch::kSuccessLowEnergy]);
EXPECT_EQ(33, return_stats_[TimeStretch::kNoStretch]);
}
TEST_F(TimeStretchTest, AccelerateFastMode) {
// TestAccelerate returns the total length change in samples.
EXPECT_EQ(21400, TestAccelerate(100, true));
EXPECT_EQ(31, return_stats_[TimeStretch::kSuccess]);
EXPECT_EQ(58, return_stats_[TimeStretch::kSuccessLowEnergy]);
EXPECT_EQ(11, return_stats_[TimeStretch::kNoStretch]);
}
} // namespace webrtc