Change how background noise mode in NetEq is set

This change prepares for switching default background noise (bgn) mode
from on to off. The actual switch will be done later.

In this change, the bgn mode is included as a setting in NetEq's config
struct. We're also removing the connection between playout modes and
bgn modes in ACM. In practice this means that bgn mode will change from
off to on for streaming mode, but since the playout modes are not used
it does not matter.

BUG=3519
R=tina.legrand@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6843 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org
2014-08-07 12:27:37 +00:00
parent 476efa2031
commit ea25784107
12 changed files with 170 additions and 207 deletions

View File

@@ -210,29 +210,25 @@ int AcmReceiver::current_sample_rate_hz() const {
// TODO(turajs): use one set of enumerators, e.g. the one defined in
// common_types.h
// TODO(henrik.lundin): This method is not used any longer. The call hierarchy
// stops in voe::Channel::SetNetEQPlayoutMode(). Remove it.
void AcmReceiver::SetPlayoutMode(AudioPlayoutMode mode) {
enum NetEqPlayoutMode playout_mode = kPlayoutOn;
enum NetEqBackgroundNoiseMode bgn_mode = kBgnOn;
switch (mode) {
case voice:
playout_mode = kPlayoutOn;
bgn_mode = kBgnOn;
break;
case fax: // No change to background noise mode.
playout_mode = kPlayoutFax;
bgn_mode = neteq_->BackgroundNoiseMode();
break;
case streaming:
playout_mode = kPlayoutStreaming;
bgn_mode = kBgnOff;
break;
case off:
playout_mode = kPlayoutOff;
bgn_mode = kBgnOff;
break;
}
neteq_->SetPlayoutMode(playout_mode);
neteq_->SetBackgroundNoiseMode(bgn_mode);
}
AudioPlayoutMode AcmReceiver::PlayoutMode() const {
@@ -800,10 +796,6 @@ bool AcmReceiver::GetSilence(int desired_sample_rate_hz, AudioFrame* frame) {
return true;
}
NetEqBackgroundNoiseMode AcmReceiver::BackgroundNoiseModeForTest() const {
return neteq_->BackgroundNoiseMode();
}
int AcmReceiver::RtpHeaderToCodecIndex(
const RTPHeader &rtp_header, const uint8_t* payload) const {
uint8_t payload_type = rtp_header.payloadType;

View File

@@ -307,12 +307,6 @@ class AcmReceiver {
//
std::vector<uint16_t> GetNackList(int round_trip_time_ms) const;
//
// Returns the background noise mode. This is only for testing and ACM is not
// calling this function. Used in acm_receiver_unittest.cc.
//
NetEqBackgroundNoiseMode BackgroundNoiseModeForTest() const;
//
// Get statistics of calls to GetAudio().
void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const;

View File

@@ -247,34 +247,19 @@ TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(SampleRate)) {
}
}
// Changing playout mode to FAX should not change the background noise mode.
TEST_F(AcmReceiverTest,
DISABLED_ON_ANDROID(PlayoutModeAndBackgroundNoiseMode)) {
EXPECT_EQ(kBgnOn, receiver_->BackgroundNoiseModeForTest()); // Default
// Verify that the playout mode is set correctly.
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(PlayoutMode)) {
receiver_->SetPlayoutMode(voice);
EXPECT_EQ(voice, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOn, receiver_->BackgroundNoiseModeForTest());
receiver_->SetPlayoutMode(streaming);
EXPECT_EQ(streaming, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOff, receiver_->BackgroundNoiseModeForTest());
receiver_->SetPlayoutMode(fax);
EXPECT_EQ(fax, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOff, receiver_->BackgroundNoiseModeForTest());
receiver_->SetPlayoutMode(off);
EXPECT_EQ(off, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOff, receiver_->BackgroundNoiseModeForTest());
// Change to voice then to FAX.
receiver_->SetPlayoutMode(voice);
EXPECT_EQ(voice, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOn, receiver_->BackgroundNoiseModeForTest());
receiver_->SetPlayoutMode(fax);
EXPECT_EQ(fax, receiver_->PlayoutMode());
EXPECT_EQ(kBgnOn, receiver_->BackgroundNoiseModeForTest());
}
TEST_F(AcmReceiverTest, DISABLED_ON_ANDROID(PostdecodingVad)) {

View File

@@ -24,7 +24,7 @@ namespace webrtc {
BackgroundNoise::BackgroundNoise(size_t num_channels)
: num_channels_(num_channels),
channel_parameters_(new ChannelParameters[num_channels_]),
mode_(kBgnOn) {
mode_(NetEq::kBgnOn) {
Reset();
}

View File

@@ -68,11 +68,11 @@ class BackgroundNoise {
// Accessors.
bool initialized() const { return initialized_; }
NetEqBackgroundNoiseMode mode() const { return mode_; }
NetEq::BackgroundNoiseMode mode() const { return mode_; }
// Sets the mode of the background noise playout for cases when there is long
// duration of packet loss.
void set_mode(NetEqBackgroundNoiseMode mode) { mode_ = mode; }
void set_mode(NetEq::BackgroundNoiseMode mode) { mode_ = mode; }
private:
static const int kThresholdIncrement = 229; // 0.0035 in Q16.
@@ -128,7 +128,7 @@ class BackgroundNoise {
size_t num_channels_;
scoped_ptr<ChannelParameters[]> channel_parameters_;
bool initialized_;
NetEqBackgroundNoiseMode mode_;
NetEq::BackgroundNoiseMode mode_;
DISALLOW_COPY_AND_ASSIGN(BackgroundNoise);
};

View File

@@ -806,7 +806,7 @@ void Expand::GenerateBackgroundNoise(int16_t* random_vector,
int16_t* buffer) {
static const int kNoiseLpcOrder = BackgroundNoise::kMaxLpcOrder;
int16_t scaled_random_vector[kMaxSampleRate / 8000 * 125];
assert(kMaxSampleRate / 8000 * 125 >= (int)num_noise_samples);
assert(static_cast<size_t>(kMaxSampleRate / 8000 * 125) >= num_noise_samples);
int16_t* noise_samples = &buffer[kNoiseLpcOrder];
if (background_noise_->initialized()) {
// Use background noise parameters.
@@ -838,8 +838,9 @@ void Expand::GenerateBackgroundNoise(int16_t* random_vector,
// Unmute the background noise.
int16_t bgn_mute_factor = background_noise_->MuteFactor(channel);
NetEqBackgroundNoiseMode bgn_mode = background_noise_->mode();
if (bgn_mode == kBgnFade && too_many_expands && bgn_mute_factor > 0) {
NetEq::BackgroundNoiseMode bgn_mode = background_noise_->mode();
if (bgn_mode == NetEq::kBgnFade && too_many_expands &&
bgn_mute_factor > 0) {
// Fade BGN to zero.
// Calculate muting slope, approximately -2^18 / fs_hz.
int16_t mute_slope;
@@ -862,8 +863,8 @@ void Expand::GenerateBackgroundNoise(int16_t* random_vector,
} else if (bgn_mute_factor < 16384) {
// If mode is kBgnOff, or if kBgnFade has started fading,
// Use regular |mute_slope|.
if (!stop_muting_ && bgn_mode != kBgnOff &&
!(bgn_mode == kBgnFade && too_many_expands)) {
if (!stop_muting_ && bgn_mode != NetEq::kBgnOff &&
!(bgn_mode == NetEq::kBgnFade && too_many_expands)) {
DspHelper::UnmuteSignal(noise_samples,
static_cast<int>(num_noise_samples),
&bgn_mute_factor,
@@ -893,7 +894,7 @@ void Expand::GenerateRandomVector(int seed_increment,
// just as good to generate all of the vector in one call.
size_t samples_generated = 0;
const size_t kMaxRandSamples = RandomVector::kRandomTableSize;
while(samples_generated < length) {
while (samples_generated < length) {
size_t rand_length = std::min(length - samples_generated, kMaxRandSamples);
random_vector_->IncreaseSeedIncrement(seed_increment);
random_vector_->Generate(rand_length, &random_vector[samples_generated]);

View File

@@ -58,27 +58,29 @@ enum NetEqPlayoutMode {
kPlayoutStreaming
};
enum NetEqBackgroundNoiseMode {
kBgnOn, // Default behavior with eternal noise.
kBgnFade, // Noise fades to zero after some time.
kBgnOff // Background noise is always zero.
};
// This is the interface class for NetEq.
class NetEq {
public:
enum BackgroundNoiseMode {
kBgnOn, // Default behavior with eternal noise.
kBgnFade, // Noise fades to zero after some time.
kBgnOff // Background noise is always zero.
};
struct Config {
Config()
: sample_rate_hz(16000),
enable_audio_classifier(false),
max_packets_in_buffer(50),
// |max_delay_ms| has the same effect as calling SetMaximumDelay().
max_delay_ms(2000) {}
max_delay_ms(2000),
background_noise_mode(kBgnOn) {}
int sample_rate_hz; // Initial vale. Will change with input data.
bool enable_audio_classifier;
int max_packets_in_buffer;
int max_delay_ms;
BackgroundNoiseMode background_noise_mode;
};
enum ReturnCodes {
@@ -259,12 +261,6 @@ class NetEq {
virtual int DecodedRtpInfo(int* sequence_number,
uint32_t* timestamp) const = 0;
// Sets the background noise mode.
virtual void SetBackgroundNoiseMode(NetEqBackgroundNoiseMode mode) = 0;
// Gets the background noise mode.
virtual NetEqBackgroundNoiseMode BackgroundNoiseMode() const = 0;
protected:
NetEq() {}

View File

@@ -44,7 +44,7 @@ NetEq* NetEq::Create(const NetEq::Config& config) {
ExpandFactory* expand_factory = new ExpandFactory;
PreemptiveExpandFactory* preemptive_expand_factory =
new PreemptiveExpandFactory;
return new NetEqImpl(config.sample_rate_hz,
return new NetEqImpl(config,
buffer_level_filter,
decoder_database,
delay_manager,

View File

@@ -49,7 +49,7 @@
namespace webrtc {
NetEqImpl::NetEqImpl(int fs,
NetEqImpl::NetEqImpl(const NetEq::Config& config,
BufferLevelFilter* buffer_level_filter,
DecoderDatabase* decoder_database,
DelayManager* delay_manager,
@@ -90,8 +90,10 @@ NetEqImpl::NetEqImpl(int fs,
first_packet_(true),
error_code_(0),
decoder_error_code_(0),
background_noise_mode_(config.background_noise_mode),
decoded_packet_sequence_number_(-1),
decoded_packet_timestamp_(0) {
int fs = config.sample_rate_hz;
if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) {
LOG(LS_ERROR) << "Sample rate " << fs << " Hz not supported. " <<
"Changing to 8000 Hz.";
@@ -384,18 +386,6 @@ int NetEqImpl::DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const {
return 0;
}
void NetEqImpl::SetBackgroundNoiseMode(NetEqBackgroundNoiseMode mode) {
CriticalSectionScoped lock(crit_sect_.get());
assert(background_noise_.get());
background_noise_->set_mode(mode);
}
NetEqBackgroundNoiseMode NetEqImpl::BackgroundNoiseMode() const {
CriticalSectionScoped lock(crit_sect_.get());
assert(background_noise_.get());
return background_noise_->mode();
}
const SyncBuffer* NetEqImpl::sync_buffer_for_test() const {
CriticalSectionScoped lock(crit_sect_.get());
return sync_buffer_.get();
@@ -1873,14 +1863,9 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) {
// Delete sync buffer and create a new one.
sync_buffer_.reset(new SyncBuffer(channels, kSyncBufferSize * fs_mult_));
// Delete BackgroundNoise object and create a new one, while preserving its
// mode.
NetEqBackgroundNoiseMode current_mode = kBgnOn;
if (background_noise_.get())
current_mode = background_noise_->mode();
// Delete BackgroundNoise object and create a new one.
background_noise_.reset(new BackgroundNoise(channels));
background_noise_->set_mode(current_mode);
background_noise_->set_mode(background_noise_mode_);
// Reset random vector.
random_vector_.Reset();

View File

@@ -58,7 +58,7 @@ class NetEqImpl : public webrtc::NetEq {
public:
// Creates a new NetEqImpl object. The object will assume ownership of all
// injected dependencies, and will delete them when done.
NetEqImpl(int fs,
NetEqImpl(const NetEq::Config& config,
BufferLevelFilter* buffer_level_filter,
DecoderDatabase* decoder_database,
DelayManager* delay_manager,
@@ -191,12 +191,6 @@ class NetEqImpl : public webrtc::NetEq {
// This method is to facilitate NACK.
virtual int DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const;
// Sets background noise mode.
virtual void SetBackgroundNoiseMode(NetEqBackgroundNoiseMode mode);
// Gets background noise mode.
virtual NetEqBackgroundNoiseMode BackgroundNoiseMode() const;
// This accessor method is only intended for testing purposes.
virtual const SyncBuffer* sync_buffer_for_test() const;
@@ -387,6 +381,7 @@ class NetEqImpl : public webrtc::NetEq {
bool first_packet_ GUARDED_BY(crit_sect_);
int error_code_ GUARDED_BY(crit_sect_); // Store last error code.
int decoder_error_code_ GUARDED_BY(crit_sect_);
const BackgroundNoiseMode background_noise_mode_ GUARDED_BY(crit_sect_);
// These values are used by NACK module to estimate time-to-play of
// a missing packet. Occasionally, NetEq might decide to decode more

View File

@@ -140,7 +140,7 @@ class NetEqImplTest : public ::testing::Test {
PreemptiveExpandFactory* preemptive_expand_factory =
new PreemptiveExpandFactory;
neteq_ = new NetEqImpl(config_.sample_rate_hz,
neteq_ = new NetEqImpl(config_,
buffer_level_filter_,
decoder_database_,
delay_manager_,

View File

@@ -214,8 +214,6 @@ class NetEqDecodingTest : public ::testing::Test {
uint8_t* payload,
int* payload_len);
void CheckBgnOff(int sampling_rate, NetEqBackgroundNoiseMode bgn_mode);
void WrapTest(uint16_t start_seq_no, uint32_t start_timestamp,
const std::set<uint16_t>& drop_seq_numbers,
bool expect_seq_no_wrap, bool expect_timestamp_wrap);
@@ -231,6 +229,7 @@ class NetEqDecodingTest : public ::testing::Test {
uint32_t PlayoutTimestamp();
NetEq* neteq_;
NetEq::Config config_;
FILE* rtp_fp_;
unsigned int sim_clock_;
int16_t out_data_[kMaxBlockSize];
@@ -248,17 +247,17 @@ const int NetEqDecodingTest::kInitSampleRateHz;
NetEqDecodingTest::NetEqDecodingTest()
: neteq_(NULL),
config_(),
rtp_fp_(NULL),
sim_clock_(0),
output_sample_rate_(kInitSampleRateHz),
algorithmic_delay_ms_(0) {
config_.sample_rate_hz = kInitSampleRateHz;
memset(out_data_, 0, sizeof(out_data_));
}
void NetEqDecodingTest::SetUp() {
NetEq::Config config;
config.sample_rate_hz = kInitSampleRateHz;
neteq_ = NetEq::Create(config);
neteq_ = NetEq::Create(config_);
NetEqNetworkStatistics stat;
ASSERT_EQ(0, neteq_->NetworkStatistics(&stat));
algorithmic_delay_ms_ = stat.current_buffer_size_ms;
@@ -425,107 +424,6 @@ void NetEqDecodingTest::PopulateCng(int frame_index,
*payload_len = 1; // Only noise level, no spectral parameters.
}
void NetEqDecodingTest::CheckBgnOff(int sampling_rate_hz,
NetEqBackgroundNoiseMode bgn_mode) {
int expected_samples_per_channel = 0;
uint8_t payload_type = 0xFF; // Invalid.
if (sampling_rate_hz == 8000) {
expected_samples_per_channel = kBlockSize8kHz;
payload_type = 93; // PCM 16, 8 kHz.
} else if (sampling_rate_hz == 16000) {
expected_samples_per_channel = kBlockSize16kHz;
payload_type = 94; // PCM 16, 16 kHZ.
} else if (sampling_rate_hz == 32000) {
expected_samples_per_channel = kBlockSize32kHz;
payload_type = 95; // PCM 16, 32 kHz.
} else {
ASSERT_TRUE(false); // Unsupported test case.
}
NetEqOutputType type;
int16_t output[kBlockSize32kHz]; // Maximum size is chosen.
int16_t input[kBlockSize32kHz]; // Maximum size is chosen.
// Payload of 10 ms of PCM16 32 kHz.
uint8_t payload[kBlockSize32kHz * sizeof(int16_t)];
// Random payload.
for (int n = 0; n < expected_samples_per_channel; ++n) {
input[n] = (rand() & ((1 << 10) - 1)) - ((1 << 5) - 1);
}
int enc_len_bytes = WebRtcPcm16b_EncodeW16(
input, expected_samples_per_channel, reinterpret_cast<int16_t*>(payload));
ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2);
WebRtcRTPHeader rtp_info;
PopulateRtpInfo(0, 0, &rtp_info);
rtp_info.header.payloadType = payload_type;
int number_channels = 0;
int samples_per_channel = 0;
uint32_t receive_timestamp = 0;
for (int n = 0; n < 10; ++n) { // Insert few packets and get audio.
number_channels = 0;
samples_per_channel = 0;
ASSERT_EQ(0, neteq_->InsertPacket(
rtp_info, payload, enc_len_bytes, receive_timestamp));
ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
&number_channels, &type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
ASSERT_EQ(kOutputNormal, type);
// Next packet.
rtp_info.header.timestamp += expected_samples_per_channel;
rtp_info.header.sequenceNumber++;
receive_timestamp += expected_samples_per_channel;
}
number_channels = 0;
samples_per_channel = 0;
// Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull one
// frame without checking speech-type. This is the first frame pulled without
// inserting any packet, and might not be labeled as PCL.
ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
&number_channels, &type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
// To be able to test the fading of background noise we need at lease to pull
// 611 frames.
const int kFadingThreshold = 611;
// Test several CNG-to-PLC packet for the expected behavior. The number 20 is
// arbitrary, but sufficiently large to test enough number of frames.
const int kNumPlcToCngTestFrames = 20;
bool plc_to_cng = false;
for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) {
number_channels = 0;
samples_per_channel = 0;
memset(output, 1, sizeof(output)); // Set to non-zero.
ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel,
&number_channels, &type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
if (type == kOutputPLCtoCNG) {
plc_to_cng = true;
double sum_squared = 0;
for (int k = 0; k < number_channels * samples_per_channel; ++k)
sum_squared += output[k] * output[k];
if (bgn_mode == kBgnOn) {
EXPECT_NE(0, sum_squared);
} else if (bgn_mode == kBgnOff || n > kFadingThreshold) {
EXPECT_EQ(0, sum_squared);
}
} else {
EXPECT_EQ(kOutputPLC, type);
}
}
EXPECT_TRUE(plc_to_cng); // Just to be sure that PLC-to-CNG has occurred.
}
TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(TestBitExactness)) {
const std::string input_rtp_file = webrtc::test::ProjectRootPath() +
"resources/audio_coding/neteq_universal_new.rtp";
@@ -993,26 +891,143 @@ TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) {
}
}
TEST_F(NetEqDecodingTest, BackgroundNoise) {
neteq_->SetBackgroundNoiseMode(kBgnOn);
CheckBgnOff(8000, kBgnOn);
CheckBgnOff(16000, kBgnOn);
CheckBgnOff(32000, kBgnOn);
EXPECT_EQ(kBgnOn, neteq_->BackgroundNoiseMode());
class NetEqBgnTest
: public NetEqDecodingTest,
public ::testing::WithParamInterface<NetEq::BackgroundNoiseMode> {
protected:
NetEqBgnTest() : NetEqDecodingTest() {
config_.background_noise_mode = GetParam();
}
neteq_->SetBackgroundNoiseMode(kBgnOff);
CheckBgnOff(8000, kBgnOff);
CheckBgnOff(16000, kBgnOff);
CheckBgnOff(32000, kBgnOff);
EXPECT_EQ(kBgnOff, neteq_->BackgroundNoiseMode());
void CheckBgnOff(int sampling_rate_hz) {
int expected_samples_per_channel = 0;
uint8_t payload_type = 0xFF; // Invalid.
if (sampling_rate_hz == 8000) {
expected_samples_per_channel = kBlockSize8kHz;
payload_type = 93; // PCM 16, 8 kHz.
} else if (sampling_rate_hz == 16000) {
expected_samples_per_channel = kBlockSize16kHz;
payload_type = 94; // PCM 16, 16 kHZ.
} else if (sampling_rate_hz == 32000) {
expected_samples_per_channel = kBlockSize32kHz;
payload_type = 95; // PCM 16, 32 kHz.
} else {
ASSERT_TRUE(false); // Unsupported test case.
}
neteq_->SetBackgroundNoiseMode(kBgnFade);
CheckBgnOff(8000, kBgnFade);
CheckBgnOff(16000, kBgnFade);
CheckBgnOff(32000, kBgnFade);
EXPECT_EQ(kBgnFade, neteq_->BackgroundNoiseMode());
NetEqOutputType type;
int16_t output[kBlockSize32kHz]; // Maximum size is chosen.
int16_t input[kBlockSize32kHz]; // Maximum size is chosen.
// Payload of 10 ms of PCM16 32 kHz.
uint8_t payload[kBlockSize32kHz * sizeof(int16_t)];
// Random payload.
for (int n = 0; n < expected_samples_per_channel; ++n) {
input[n] = (rand() & ((1 << 10) - 1)) - ((1 << 5) - 1);
}
int enc_len_bytes =
WebRtcPcm16b_EncodeW16(input,
expected_samples_per_channel,
reinterpret_cast<int16_t*>(payload));
ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2);
WebRtcRTPHeader rtp_info;
PopulateRtpInfo(0, 0, &rtp_info);
rtp_info.header.payloadType = payload_type;
int number_channels = 0;
int samples_per_channel = 0;
uint32_t receive_timestamp = 0;
for (int n = 0; n < 10; ++n) { // Insert few packets and get audio.
number_channels = 0;
samples_per_channel = 0;
ASSERT_EQ(0,
neteq_->InsertPacket(
rtp_info, payload, enc_len_bytes, receive_timestamp));
ASSERT_EQ(0,
neteq_->GetAudio(kBlockSize32kHz,
output,
&samples_per_channel,
&number_channels,
&type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
ASSERT_EQ(kOutputNormal, type);
// Next packet.
rtp_info.header.timestamp += expected_samples_per_channel;
rtp_info.header.sequenceNumber++;
receive_timestamp += expected_samples_per_channel;
}
number_channels = 0;
samples_per_channel = 0;
// Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull
// one frame without checking speech-type. This is the first frame pulled
// without inserting any packet, and might not be labeled as PLC.
ASSERT_EQ(0,
neteq_->GetAudio(kBlockSize32kHz,
output,
&samples_per_channel,
&number_channels,
&type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
// To be able to test the fading of background noise we need at lease to
// pull 611 frames.
const int kFadingThreshold = 611;
// Test several CNG-to-PLC packet for the expected behavior. The number 20
// is arbitrary, but sufficiently large to test enough number of frames.
const int kNumPlcToCngTestFrames = 20;
bool plc_to_cng = false;
for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) {
number_channels = 0;
samples_per_channel = 0;
memset(output, 1, sizeof(output)); // Set to non-zero.
ASSERT_EQ(0,
neteq_->GetAudio(kBlockSize32kHz,
output,
&samples_per_channel,
&number_channels,
&type));
ASSERT_EQ(1, number_channels);
ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
if (type == kOutputPLCtoCNG) {
plc_to_cng = true;
double sum_squared = 0;
for (int k = 0; k < number_channels * samples_per_channel; ++k)
sum_squared += output[k] * output[k];
if (config_.background_noise_mode == NetEq::kBgnOn) {
EXPECT_NE(0, sum_squared);
} else if (config_.background_noise_mode == NetEq::kBgnOff ||
n > kFadingThreshold) {
EXPECT_EQ(0, sum_squared);
}
} else {
EXPECT_EQ(kOutputPLC, type);
}
}
EXPECT_TRUE(plc_to_cng); // Just to be sure that PLC-to-CNG has occurred.
}
};
TEST_P(NetEqBgnTest, BackgroundNoise) {
CheckBgnOff(8000);
CheckBgnOff(16000);
CheckBgnOff(32000);
}
INSTANTIATE_TEST_CASE_P(BgnModes,
NetEqBgnTest,
::testing::Values(NetEq::kBgnOn,
NetEq::kBgnOff,
NetEq::kBgnFade));
TEST_F(NetEqDecodingTest, SyncPacketInsert) {
WebRtcRTPHeader rtp_info;
uint32_t receive_timestamp = 0;