New ACM test to trigger audio glitch when switching output sample rate
This CL implements a new unit test. The test is designed to trigger a problem in ACM where switching the desired output frequency creates a short discontinuity in the output audio. The problem itself is not solved in this CL, but the failing test is disabled for now. BUG=3919 R=kwiberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/23019004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7443 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -164,6 +164,7 @@ void AcmReceiveTestOldApi::Run() {
|
||||
}
|
||||
ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame));
|
||||
clock_.AdvanceTimeMilliseconds(10);
|
||||
AfterGetAudio();
|
||||
}
|
||||
|
||||
// Insert packet after converting from RTPHeader to WebRtcRTPHeader.
|
||||
@ -183,5 +184,31 @@ void AcmReceiveTestOldApi::Run() {
|
||||
}
|
||||
}
|
||||
|
||||
AcmReceiveTestToggleOutputFreqOldApi::AcmReceiveTestToggleOutputFreqOldApi(
|
||||
PacketSource* packet_source,
|
||||
AudioSink* audio_sink,
|
||||
int output_freq_hz_1,
|
||||
int output_freq_hz_2,
|
||||
int toggle_period_ms,
|
||||
NumOutputChannels exptected_output_channels)
|
||||
: AcmReceiveTestOldApi(packet_source,
|
||||
audio_sink,
|
||||
output_freq_hz_1,
|
||||
exptected_output_channels),
|
||||
output_freq_hz_1_(output_freq_hz_1),
|
||||
output_freq_hz_2_(output_freq_hz_2),
|
||||
toggle_period_ms_(toggle_period_ms),
|
||||
last_toggle_time_ms_(clock_.TimeInMilliseconds()) {
|
||||
}
|
||||
|
||||
void AcmReceiveTestToggleOutputFreqOldApi::AfterGetAudio() {
|
||||
if (clock_.TimeInMilliseconds() >= last_toggle_time_ms_ + toggle_period_ms_) {
|
||||
output_freq_hz_ = (output_freq_hz_ == output_freq_hz_1_)
|
||||
? output_freq_hz_2_
|
||||
: output_freq_hz_1_;
|
||||
last_toggle_time_ms_ = clock_.TimeInMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
@ -47,17 +47,42 @@ class AcmReceiveTestOldApi {
|
||||
// Runs the test and returns true if successful.
|
||||
void Run();
|
||||
|
||||
private:
|
||||
protected:
|
||||
// Method is called after each block of output audio is received from ACM.
|
||||
virtual void AfterGetAudio() {}
|
||||
|
||||
SimulatedClock clock_;
|
||||
scoped_ptr<AudioCodingModule> acm_;
|
||||
PacketSource* packet_source_;
|
||||
AudioSink* audio_sink_;
|
||||
const int output_freq_hz_;
|
||||
int output_freq_hz_;
|
||||
NumOutputChannels exptected_output_channels_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AcmReceiveTestOldApi);
|
||||
};
|
||||
|
||||
// This test toggles the output frequency every |toggle_period_ms|. The test
|
||||
// starts with |output_freq_hz_1|. Except for the toggling, it does the same
|
||||
// thing as AcmReceiveTestOldApi.
|
||||
class AcmReceiveTestToggleOutputFreqOldApi : public AcmReceiveTestOldApi {
|
||||
public:
|
||||
AcmReceiveTestToggleOutputFreqOldApi(
|
||||
PacketSource* packet_source,
|
||||
AudioSink* audio_sink,
|
||||
int output_freq_hz_1,
|
||||
int output_freq_hz_2,
|
||||
int toggle_period_ms,
|
||||
NumOutputChannels exptected_output_channels);
|
||||
|
||||
protected:
|
||||
void AfterGetAudio() OVERRIDE;
|
||||
|
||||
const int output_freq_hz_1_;
|
||||
const int output_freq_hz_2_;
|
||||
const int toggle_period_ms_;
|
||||
int64_t last_toggle_time_ms_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h"
|
||||
#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
|
||||
@ -935,4 +936,105 @@ TEST_F(AcmSenderBitExactnessOldApi, Opus_stereo_20ms) {
|
||||
test::AcmReceiveTestOldApi::kStereoOutput);
|
||||
}
|
||||
|
||||
// This test fixture is implemented to run ACM and change the desired output
|
||||
// frequency during the call. The input packets are simply PCM16b-wb encoded
|
||||
// payloads with a constant value of |kSampleValue|. The test fixture itself
|
||||
// acts as PacketSource in between the receive test class and the constant-
|
||||
// payload packet source class. The output is both written to file, and analyzed
|
||||
// in this test fixture.
|
||||
class AcmSwitchingOutputFrequencyOldApi : public ::testing::Test,
|
||||
public test::PacketSource,
|
||||
public test::AudioSink {
|
||||
protected:
|
||||
static const size_t kTestNumPackets = 100;
|
||||
static const int kEncodedSampleRateHz = 16000;
|
||||
static const size_t kPayloadLenSamples = 30 * kEncodedSampleRateHz / 1000;
|
||||
static const int kPayloadType = 108; // Default payload type for PCM16b-wb.
|
||||
|
||||
AcmSwitchingOutputFrequencyOldApi()
|
||||
: first_output_(true),
|
||||
num_packets_(0),
|
||||
packet_source_(kPayloadLenSamples,
|
||||
kSampleValue,
|
||||
kEncodedSampleRateHz,
|
||||
kPayloadType),
|
||||
high_output_freq_(0),
|
||||
has_toggled_(false) {}
|
||||
|
||||
void Run(int low_output_freq, int high_output_freq, int toggle_period_ms) {
|
||||
// Set up the receiver used to decode the packets and verify the decoded
|
||||
// output.
|
||||
const std::string output_file_name =
|
||||
webrtc::test::OutputPath() +
|
||||
::testing::UnitTest::GetInstance()
|
||||
->current_test_info()
|
||||
->test_case_name() +
|
||||
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() +
|
||||
"_output.pcm";
|
||||
test::OutputAudioFile output_file(output_file_name);
|
||||
// Have the output audio sent both to file and to the WriteArray method in
|
||||
// this class.
|
||||
test::AudioSinkFork output(this, &output_file);
|
||||
test::AcmReceiveTestToggleOutputFreqOldApi receive_test(
|
||||
this,
|
||||
&output,
|
||||
low_output_freq,
|
||||
high_output_freq,
|
||||
toggle_period_ms,
|
||||
test::AcmReceiveTestOldApi::kMonoOutput);
|
||||
ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs());
|
||||
high_output_freq_ = high_output_freq;
|
||||
|
||||
// This is where the actual test is executed.
|
||||
receive_test.Run();
|
||||
}
|
||||
|
||||
// Inherited from test::PacketSource.
|
||||
test::Packet* NextPacket() OVERRIDE {
|
||||
// Check if it is time to terminate the test. The packet source is of type
|
||||
// ConstantPcmPacketSource, which is infinite, so we must end the test
|
||||
// "manually".
|
||||
if (num_packets_++ > kTestNumPackets) {
|
||||
EXPECT_TRUE(has_toggled_);
|
||||
return NULL; // Test ended.
|
||||
}
|
||||
|
||||
// Get the next packet from the source.
|
||||
return packet_source_.NextPacket();
|
||||
}
|
||||
|
||||
// Inherited from test::AudioSink.
|
||||
bool WriteArray(const int16_t* audio, size_t num_samples) {
|
||||
// Skip checking the first output frame, since it has a number of zeros
|
||||
// due to how NetEq is initialized.
|
||||
if (first_output_) {
|
||||
first_output_ = false;
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < num_samples; ++i) {
|
||||
EXPECT_EQ(kSampleValue, audio[i]);
|
||||
}
|
||||
if (num_samples ==
|
||||
static_cast<size_t>(high_output_freq_ / 100)) // Size of 10 ms frame.
|
||||
has_toggled_ = true;
|
||||
// The return value does not say if the values match the expectation, just
|
||||
// that the method could process the samples.
|
||||
return true;
|
||||
}
|
||||
|
||||
const int16_t kSampleValue = 1000;
|
||||
bool first_output_;
|
||||
size_t num_packets_;
|
||||
test::ConstantPcmPacketSource packet_source_;
|
||||
int high_output_freq_;
|
||||
bool has_toggled_;
|
||||
};
|
||||
|
||||
TEST_F(AcmSwitchingOutputFrequencyOldApi, TestWithoutToggling) {
|
||||
Run(16000, 16000, 1000);
|
||||
}
|
||||
|
||||
TEST_F(AcmSwitchingOutputFrequencyOldApi, DISABLED_TestWithToggling) {
|
||||
Run(16000, 32000, 1000);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
Reference in New Issue
Block a user