#include "webrtc/audio_processing/unittest.pb.h"
#endif
-#if (defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)) || \
- (defined(WEBRTC_LINUX) && defined(WEBRTC_ARCH_X86_64) && !defined(NDEBUG))
-# define WEBRTC_AUDIOPROC_BIT_EXACT
-#endif
-
namespace webrtc {
namespace {
// TODO(bjornv): This is not feasible until the functionality has been
-// re-implemented; see comment at the bottom of this file.
+// re-implemented; see comment at the bottom of this file. For now, the user has
+// to hard code the |write_ref_data| value.
// When false, this will compare the output data with the results stored to
// file. This is the typical case. When the file should be updated, it can
// be set to true with the command-line switch --write_ref_data.
-#ifdef WEBRTC_AUDIOPROC_BIT_EXACT
bool write_ref_data = false;
const int kChannels[] = {1, 2};
const size_t kChannelsSize = sizeof(kChannels) / sizeof(*kChannels);
-#endif
const int kSampleRates[] = {8000, 16000, 32000};
const size_t kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
EXPECT_NOERR(ap->voice_detection()->Enable(true));
}
-#ifdef WEBRTC_AUDIOPROC_BIT_EXACT
-// These functions are only used by the bit-exact test.
+// These functions are only used by ApmTest.Process.
template <class T>
T AbsValue(T a) {
return a > 0 ? a: -a;
void OpenFileAndWriteMessage(const std::string filename,
const ::google::protobuf::MessageLite& msg) {
+#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
FILE* file = fopen(filename.c_str(), "wb");
ASSERT_TRUE(file != NULL);
ASSERT_EQ(static_cast<size_t>(size),
fwrite(array.get(), sizeof(array[0]), size, file));
fclose(file);
+#else
+ std::cout << "Warning: Writing new reference is only allowed on Linux!"
+ << std::endl;
+#endif
}
-#endif // WEBRTC_AUDIOPROC_BIT_EXACT
std::string ResourceFilePath(std::string name, int sample_rate_hz) {
std::ostringstream ss;
for (int i = 1; i < 3; i++) {
TestChangingChannels(i, kNoErr);
EXPECT_EQ(i, apm_->num_input_channels());
- EXPECT_EQ(i, apm_->num_reverse_channels());
+ // We always force the number of reverse channels used for processing to 1.
+ EXPECT_EQ(1, apm_->num_reverse_channels());
}
}
const int num_output_channels = test->num_output_channels();
const int samples_per_channel = test->sample_rate() *
AudioProcessing::kChunkSizeMs / 1000;
- const int output_length = samples_per_channel * num_output_channels;
+ const int output_length = samples_per_channel * num_output_channels;
Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
num_input_channels, num_output_channels, num_render_channels, true);
// TODO(andrew): Add a test to process a few frames with different combinations
// of enabled components.
-// TODO(andrew): Make this test more robust such that it can be run on multiple
-// platforms. It currently requires bit-exactness.
-#ifdef WEBRTC_AUDIOPROC_BIT_EXACT
-TEST_F(ApmTest, DISABLED_ON_ANDROID(Process)) {
+TEST_F(ApmTest, Process) {
GOOGLE_PROTOBUF_VERIFY_VERSION;
audioproc::OutputData ref_data;
#endif
if (!write_ref_data) {
- EXPECT_EQ(test->has_echo_count(), has_echo_count);
- EXPECT_EQ(test->has_voice_count(), has_voice_count);
- EXPECT_EQ(test->is_saturated_count(), is_saturated_count);
+ const int kIntNear = 1;
+ // When running the test on a N7 we get a {2, 6} difference of
+ // |has_voice_count| and |max_output_average| is up to 18 higher.
+ // All numbers being consistently higher on N7 compare to ref_data.
+ // TODO(bjornv): If we start getting more of these offsets on Android we
+ // should consider a different approach. Either using one slack for all,
+ // or generate a separate android reference.
+#if defined(WEBRTC_ANDROID)
+ const int kHasVoiceCountOffset = 3;
+ const int kHasVoiceCountNear = 3;
+ const int kMaxOutputAverageOffset = 9;
+ const int kMaxOutputAverageNear = 9;
+#else
+ const int kHasVoiceCountOffset = 0;
+ const int kHasVoiceCountNear = kIntNear;
+ const int kMaxOutputAverageOffset = 0;
+ const int kMaxOutputAverageNear = kIntNear;
+#endif
+ EXPECT_NEAR(test->has_echo_count(), has_echo_count, kIntNear);
+ EXPECT_NEAR(test->has_voice_count(),
+ has_voice_count - kHasVoiceCountOffset,
+ kHasVoiceCountNear);
+ EXPECT_NEAR(test->is_saturated_count(), is_saturated_count, kIntNear);
- EXPECT_EQ(test->analog_level_average(), analog_level_average);
- EXPECT_EQ(test->max_output_average(), max_output_average);
+ EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
+ EXPECT_NEAR(test->max_output_average(),
+ max_output_average - kMaxOutputAverageOffset,
+ kMaxOutputAverageNear);
#if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
audioproc::Test::EchoMetrics reference = test->echo_metrics();
TestStats(echo_metrics.a_nlp,
reference.a_nlp());
+ const double kFloatNear = 0.0005;
audioproc::Test::DelayMetrics reference_delay = test->delay_metrics();
- EXPECT_EQ(reference_delay.median(), median);
- EXPECT_EQ(reference_delay.std(), std);
+ EXPECT_NEAR(reference_delay.median(), median, kIntNear);
+ EXPECT_NEAR(reference_delay.std(), std, kIntNear);
- EXPECT_EQ(test->rms_level(), rms_level);
+ EXPECT_NEAR(test->rms_level(), rms_level, kIntNear);
- EXPECT_FLOAT_EQ(test->ns_speech_probability_average(),
- ns_speech_prob_average);
+ EXPECT_NEAR(test->ns_speech_probability_average(),
+ ns_speech_prob_average,
+ kFloatNear);
#endif
} else {
test->set_has_echo_count(has_echo_count);
}
}
-#endif // WEBRTC_AUDIOPROC_BIT_EXACT
-
TEST_F(ApmTest, NoErrorsWithKeyboardChannel) {
struct ChannelFormat {
AudioProcessing::ChannelLayout in_layout;
#if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
INSTANTIATE_TEST_CASE_P(
CommonFormats, AudioProcessingTest, testing::Values(
- std::tr1::make_tuple(48000, 48000, 48000, 25),
- std::tr1::make_tuple(48000, 48000, 32000, 25),
- std::tr1::make_tuple(48000, 48000, 16000, 25),
- std::tr1::make_tuple(48000, 44100, 48000, 20),
- std::tr1::make_tuple(48000, 44100, 32000, 20),
- std::tr1::make_tuple(48000, 44100, 16000, 20),
- std::tr1::make_tuple(48000, 32000, 48000, 25),
- std::tr1::make_tuple(48000, 32000, 32000, 25),
- std::tr1::make_tuple(48000, 32000, 16000, 25),
- std::tr1::make_tuple(48000, 16000, 48000, 25),
- std::tr1::make_tuple(48000, 16000, 32000, 25),
- std::tr1::make_tuple(48000, 16000, 16000, 25),
+ std::tr1::make_tuple(48000, 48000, 48000, 20),
+ std::tr1::make_tuple(48000, 48000, 32000, 20),
+ std::tr1::make_tuple(48000, 48000, 16000, 20),
+ std::tr1::make_tuple(48000, 44100, 48000, 15),
+ std::tr1::make_tuple(48000, 44100, 32000, 15),
+ std::tr1::make_tuple(48000, 44100, 16000, 15),
+ std::tr1::make_tuple(48000, 32000, 48000, 20),
+ std::tr1::make_tuple(48000, 32000, 32000, 20),
+ std::tr1::make_tuple(48000, 32000, 16000, 20),
+ std::tr1::make_tuple(48000, 16000, 48000, 20),
+ std::tr1::make_tuple(48000, 16000, 32000, 20),
+ std::tr1::make_tuple(48000, 16000, 16000, 20),
std::tr1::make_tuple(44100, 48000, 48000, 20),
std::tr1::make_tuple(44100, 48000, 32000, 20),
std::tr1::make_tuple(44100, 48000, 16000, 20),
- std::tr1::make_tuple(44100, 44100, 48000, 20),
- std::tr1::make_tuple(44100, 44100, 32000, 20),
- std::tr1::make_tuple(44100, 44100, 16000, 20),
+ std::tr1::make_tuple(44100, 44100, 48000, 15),
+ std::tr1::make_tuple(44100, 44100, 32000, 15),
+ std::tr1::make_tuple(44100, 44100, 16000, 15),
std::tr1::make_tuple(44100, 32000, 48000, 20),
std::tr1::make_tuple(44100, 32000, 32000, 20),
std::tr1::make_tuple(44100, 32000, 16000, 20),
std::tr1::make_tuple(32000, 32000, 48000, 30),
std::tr1::make_tuple(32000, 32000, 32000, 0),
std::tr1::make_tuple(32000, 32000, 16000, 30),
- std::tr1::make_tuple(32000, 16000, 48000, 25),
- std::tr1::make_tuple(32000, 16000, 32000, 25),
- std::tr1::make_tuple(32000, 16000, 16000, 25),
+ std::tr1::make_tuple(32000, 16000, 48000, 20),
+ std::tr1::make_tuple(32000, 16000, 32000, 20),
+ std::tr1::make_tuple(32000, 16000, 16000, 20),
std::tr1::make_tuple(16000, 48000, 48000, 25),
std::tr1::make_tuple(16000, 48000, 32000, 25),