Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright (c) 2016 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 #include <cmath> | |
| 11 #include <memory> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "webrtc/base/array_view.h" | |
| 15 #include "webrtc/base/safe_conversions.h" | |
| 16 #include "webrtc/modules/audio_processing/rms_level.h" | |
| 17 #include "webrtc/test/gtest.h" | |
| 18 | |
| 19 namespace webrtc { | |
| 20 namespace { | |
| 21 constexpr int kSampleRateHz = 48000; | |
|
peah-webrtc
2016/11/25 12:26:25
You probably could (should?) use AudioProcessing::
hlundin-webrtc
2016/11/25 13:09:00
Neither the test, nor the code it tests depend on
| |
| 22 constexpr size_t kBlockSizeSamples = kSampleRateHz / 100; | |
| 23 | |
| 24 std::unique_ptr<RMSLevel> RunTest(rtc::ArrayView<const int16_t> input) { | |
| 25 std::unique_ptr<RMSLevel> level(new RMSLevel); | |
| 26 for (size_t n = 0; n + kBlockSizeSamples <= input.size(); | |
| 27 n += kBlockSizeSamples) { | |
| 28 level->Process(input.subview(n, kBlockSizeSamples).data(), | |
|
peah-webrtc
2016/11/25 12:26:25
Nice!
hlundin-webrtc
2016/11/25 13:09:00
It will be even nicer in the next CL :)
| |
| 29 kBlockSizeSamples); | |
| 30 } | |
| 31 return level; | |
| 32 } | |
| 33 | |
| 34 std::vector<int16_t> CreateSinusoid(int frequency_hz, | |
| 35 int amplitude, | |
| 36 size_t num_samples) { | |
| 37 std::vector<int16_t> x(num_samples); | |
| 38 const float pi = std::acos(-1); | |
|
peah-webrtc
2016/11/25 12:26:25
Why not use M_PI?
hlundin-webrtc
2016/11/25 13:09:00
Done.
| |
| 39 for (size_t n = 0; n < num_samples; ++n) { | |
| 40 x[n] = rtc::saturated_cast<int16_t>( | |
| 41 amplitude * sin(2 * pi * n * frequency_hz / kSampleRateHz)); | |
| 42 } | |
| 43 return x; | |
| 44 } | |
| 45 } // namespace | |
| 46 | |
| 47 TEST(RmsLevelTest, Run1000HzFullScale) { | |
| 48 auto x = CreateSinusoid(1000, INT16_MAX, kSampleRateHz); | |
| 49 auto level = RunTest(x); | |
| 50 EXPECT_EQ(3, level->RMS()); // -3 dBFS | |
| 51 } | |
| 52 | |
| 53 TEST(RmsLevelTest, Run1000HzHalfScale) { | |
| 54 auto x = CreateSinusoid(1000, INT16_MAX / 2, kSampleRateHz); | |
| 55 auto level = RunTest(x); | |
| 56 EXPECT_EQ(9, level->RMS()); // -9 dBFS | |
| 57 } | |
| 58 | |
| 59 TEST(RmsLevelTest, RunZeros) { | |
| 60 std::vector<int16_t> x(kSampleRateHz, 0); // 1 second of pure silence. | |
| 61 auto level = RunTest(x); | |
| 62 EXPECT_EQ(127, level->RMS()); | |
| 63 } | |
| 64 | |
| 65 TEST(RmsLevelTest, NoSamples) { | |
| 66 RMSLevel level; | |
| 67 EXPECT_EQ(127, level.RMS()); // Return minimum if no samples are given. | |
| 68 } | |
| 69 | |
| 70 TEST(RmsLevelTest, PollTwice) { | |
| 71 auto x = CreateSinusoid(1000, INT16_MAX, kSampleRateHz); | |
| 72 auto level = RunTest(x); | |
| 73 level->RMS(); | |
| 74 EXPECT_EQ(127, level->RMS()); // Stats should be reset at this point. | |
| 75 } | |
| 76 | |
| 77 TEST(RmsLevelTest, Reset) { | |
| 78 auto x = CreateSinusoid(1000, INT16_MAX, kSampleRateHz); | |
| 79 auto level = RunTest(x); | |
| 80 level->Reset(); | |
| 81 EXPECT_EQ(127, level->RMS()); // Stats should be reset at this point. | |
| 82 } | |
| 83 | |
| 84 // Inserts 1 second of full-scale sinusoid, followed by 1 second of muted. | |
| 85 TEST(RmsLevelTest, ProcessMuted) { | |
| 86 auto x = CreateSinusoid(1000, INT16_MAX, kSampleRateHz); | |
| 87 auto level = RunTest(x); | |
| 88 level->ProcessMuted(kSampleRateHz); | |
| 89 EXPECT_EQ(6, level->RMS()); // Average RMS halved due to the silence. | |
| 90 } | |
| 91 | |
| 92 } // namespace webrtc | |
| OLD | NEW |