loudness_histogram_unittest.cc (3166B)
1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // Use CreateHistUnittestFile.m to generate the input file. 12 13 #include "modules/audio_processing/agc/loudness_histogram.h" 14 15 #include <algorithm> 16 #include <cmath> 17 #include <cstdio> 18 #include <memory> 19 #include <string> 20 21 #include "absl/strings/string_view.h" 22 #include "modules/audio_processing/agc/utility.h" 23 #include "test/gtest.h" 24 #include "test/testsupport/file_utils.h" 25 26 namespace webrtc { 27 28 struct InputOutput { 29 double rms; 30 double activity_probability; 31 double audio_content; 32 double loudness; 33 }; 34 35 constexpr double kRelativeErrTol = 1e-10; 36 37 class LoudnessHistogramTest : public ::testing::Test { 38 protected: 39 void RunTest(bool enable_circular_buff, absl::string_view filename); 40 41 private: 42 void TestClean(); 43 std::unique_ptr<LoudnessHistogram> hist_; 44 }; 45 46 void LoudnessHistogramTest::TestClean() { 47 EXPECT_EQ(hist_->CurrentRms(), 7.59621091765857e-02); 48 EXPECT_EQ(hist_->AudioContent(), 0); 49 EXPECT_EQ(hist_->num_updates(), 0); 50 } 51 52 void LoudnessHistogramTest::RunTest(bool enable_circular_buff, 53 absl::string_view filename) { 54 FILE* in_file = fopen(std::string(filename).c_str(), "rb"); 55 ASSERT_TRUE(in_file != nullptr); 56 if (enable_circular_buff) { 57 int buffer_size; 58 EXPECT_EQ(fread(&buffer_size, sizeof(buffer_size), 1, in_file), 1u); 59 hist_.reset(LoudnessHistogram::Create(buffer_size)); 60 } else { 61 hist_.reset(LoudnessHistogram::Create()); 62 } 63 TestClean(); 64 65 InputOutput io; 66 int num_updates = 0; 67 while (fread(&io, sizeof(InputOutput), 1, in_file) == 1) { 68 if (io.rms < 0) { 69 // We have to reset. 70 hist_->Reset(); 71 TestClean(); 72 num_updates = 0; 73 // Read the next chunk of input. 74 if (fread(&io, sizeof(InputOutput), 1, in_file) != 1) 75 break; 76 } 77 hist_->Update(io.rms, io.activity_probability); 78 num_updates++; 79 EXPECT_EQ(hist_->num_updates(), num_updates); 80 double audio_content = hist_->AudioContent(); 81 82 double abs_err = 83 std::min(audio_content, io.audio_content) * kRelativeErrTol; 84 85 ASSERT_NEAR(audio_content, io.audio_content, abs_err); 86 double current_loudness = Linear2Loudness(hist_->CurrentRms()); 87 abs_err = 88 std::min(fabs(current_loudness), fabs(io.loudness)) * kRelativeErrTol; 89 ASSERT_NEAR(current_loudness, io.loudness, abs_err); 90 } 91 fclose(in_file); 92 } 93 94 TEST_F(LoudnessHistogramTest, ActiveCircularBuffer) { 95 RunTest(true, test::ResourcePath( 96 "audio_processing/agc/agc_with_circular_buffer", "dat") 97 .c_str()); 98 } 99 100 TEST_F(LoudnessHistogramTest, InactiveCircularBuffer) { 101 RunTest(false, test::ResourcePath( 102 "audio_processing/agc/agc_no_circular_buffer", "dat") 103 .c_str()); 104 } 105 106 } // namespace webrtc