1 /*
2 * Copyright (c) 2017 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 #include "modules/audio_device/include/test_audio_device.h"
12
13 #include <algorithm>
14 #include <array>
15
16 #include "api/array_view.h"
17 #include "common_audio/wav_file.h"
18 #include "common_audio/wav_header.h"
19 #include "rtc_base/logging.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22 #include "test/testsupport/file_utils.h"
23
24 namespace webrtc {
25
26 namespace {
27
RunTest(const std::vector<int16_t> & input_samples,const std::vector<int16_t> & expected_samples,size_t samples_per_frame)28 void RunTest(const std::vector<int16_t>& input_samples,
29 const std::vector<int16_t>& expected_samples,
30 size_t samples_per_frame) {
31 const ::testing::TestInfo* const test_info =
32 ::testing::UnitTest::GetInstance()->current_test_info();
33
34 const std::string output_filename =
35 test::OutputPath() + "BoundedWavFileWriterTest_" + test_info->name() +
36 "_" + std::to_string(std::rand()) + ".wav";
37
38 static const size_t kSamplesPerFrame = 8;
39 static const int kSampleRate = kSamplesPerFrame * 100;
40 EXPECT_EQ(TestAudioDeviceModule::SamplesPerFrame(kSampleRate),
41 kSamplesPerFrame);
42
43 // Test through file name API.
44 {
45 std::unique_ptr<TestAudioDeviceModule::Renderer> writer =
46 TestAudioDeviceModule::CreateBoundedWavFileWriter(output_filename, 800);
47
48 for (size_t i = 0; i < input_samples.size(); i += kSamplesPerFrame) {
49 EXPECT_TRUE(writer->Render(rtc::ArrayView<const int16_t>(
50 &input_samples[i],
51 std::min(kSamplesPerFrame, input_samples.size() - i))));
52 }
53 }
54
55 {
56 WavReader reader(output_filename);
57 std::vector<int16_t> read_samples(expected_samples.size());
58 EXPECT_EQ(expected_samples.size(),
59 reader.ReadSamples(read_samples.size(), read_samples.data()));
60 EXPECT_EQ(expected_samples, read_samples);
61
62 EXPECT_EQ(0u, reader.ReadSamples(read_samples.size(), read_samples.data()));
63 }
64
65 remove(output_filename.c_str());
66 }
67 } // namespace
68
TEST(BoundedWavFileWriterTest,NoSilence)69 TEST(BoundedWavFileWriterTest, NoSilence) {
70 static const std::vector<int16_t> kInputSamples = {
71 75, 1234, 243, -1231, -22222, 0, 3, 88,
72 1222, -1213, -13222, -7, -3525, 5787, -25247, 8};
73 static const std::vector<int16_t> kExpectedSamples = kInputSamples;
74 RunTest(kInputSamples, kExpectedSamples, 8);
75 }
76
TEST(BoundedWavFileWriterTest,SomeStartSilence)77 TEST(BoundedWavFileWriterTest, SomeStartSilence) {
78 static const std::vector<int16_t> kInputSamples = {
79 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, -13222, -7, -3525, 5787, -25247, 8};
80 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin() + 10,
81 kInputSamples.end());
82 RunTest(kInputSamples, kExpectedSamples, 8);
83 }
84
TEST(BoundedWavFileWriterTest,NegativeStartSilence)85 TEST(BoundedWavFileWriterTest, NegativeStartSilence) {
86 static const std::vector<int16_t> kInputSamples = {
87 0, -4, -6, 0, 3, 0, 0, 0, 0, 3, -13222, -7, -3525, 5787, -25247, 8};
88 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin() + 2,
89 kInputSamples.end());
90 RunTest(kInputSamples, kExpectedSamples, 8);
91 }
92
TEST(BoundedWavFileWriterTest,SomeEndSilence)93 TEST(BoundedWavFileWriterTest, SomeEndSilence) {
94 static const std::vector<int16_t> kInputSamples = {
95 75, 1234, 243, -1231, -22222, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
96 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin(),
97 kInputSamples.end() - 9);
98 RunTest(kInputSamples, kExpectedSamples, 8);
99 }
100
TEST(BoundedWavFileWriterTest,DoubleEndSilence)101 TEST(BoundedWavFileWriterTest, DoubleEndSilence) {
102 static const std::vector<int16_t> kInputSamples = {
103 75, 1234, 243, -1231, -22222, 0, 0, 0,
104 0, -1213, -13222, -7, -3525, 5787, 0, 0};
105 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin(),
106 kInputSamples.end() - 2);
107 RunTest(kInputSamples, kExpectedSamples, 8);
108 }
109
TEST(BoundedWavFileWriterTest,DoubleSilence)110 TEST(BoundedWavFileWriterTest, DoubleSilence) {
111 static const std::vector<int16_t> kInputSamples = {0, -1213, -13222, -7,
112 -3525, 5787, 0, 0};
113 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin() + 1,
114 kInputSamples.end() - 2);
115 RunTest(kInputSamples, kExpectedSamples, 8);
116 }
117
TEST(BoundedWavFileWriterTest,EndSilenceCutoff)118 TEST(BoundedWavFileWriterTest, EndSilenceCutoff) {
119 static const std::vector<int16_t> kInputSamples = {
120 75, 1234, 243, -1231, -22222, 0, 1, 0, 0, 0, 0};
121 static const std::vector<int16_t> kExpectedSamples(kInputSamples.begin(),
122 kInputSamples.end() - 4);
123 RunTest(kInputSamples, kExpectedSamples, 8);
124 }
125
TEST(WavFileReaderTest,RepeatedTrueWithSingleFrameFileReadTwice)126 TEST(WavFileReaderTest, RepeatedTrueWithSingleFrameFileReadTwice) {
127 static const std::vector<int16_t> kInputSamples = {75, 1234, 243, -1231,
128 -22222, 0, 3, 88};
129 static const rtc::BufferT<int16_t> kExpectedSamples(kInputSamples.data(),
130 kInputSamples.size());
131
132 const std::string output_filename = test::OutputPath() +
133 "WavFileReaderTest_RepeatedTrue_" +
134 std::to_string(std::rand()) + ".wav";
135
136 static const size_t kSamplesPerFrame = 8;
137 static const int kSampleRate = kSamplesPerFrame * 100;
138 EXPECT_EQ(TestAudioDeviceModule::SamplesPerFrame(kSampleRate),
139 kSamplesPerFrame);
140
141 // Create wav file to read.
142 {
143 std::unique_ptr<TestAudioDeviceModule::Renderer> writer =
144 TestAudioDeviceModule::CreateWavFileWriter(output_filename, 800);
145
146 for (size_t i = 0; i < kInputSamples.size(); i += kSamplesPerFrame) {
147 EXPECT_TRUE(writer->Render(rtc::ArrayView<const int16_t>(
148 &kInputSamples[i],
149 std::min(kSamplesPerFrame, kInputSamples.size() - i))));
150 }
151 }
152
153 {
154 std::unique_ptr<TestAudioDeviceModule::Capturer> reader =
155 TestAudioDeviceModule::CreateWavFileReader(output_filename, true);
156 rtc::BufferT<int16_t> buffer(kExpectedSamples.size());
157 EXPECT_TRUE(reader->Capture(&buffer));
158 EXPECT_EQ(kExpectedSamples, buffer);
159 EXPECT_TRUE(reader->Capture(&buffer));
160 EXPECT_EQ(kExpectedSamples, buffer);
161 }
162
163 remove(output_filename.c_str());
164 }
165
TEST(PulsedNoiseCapturerTest,SetMaxAmplitude)166 TEST(PulsedNoiseCapturerTest, SetMaxAmplitude) {
167 const int16_t kAmplitude = 50;
168 std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer> capturer =
169 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
170 kAmplitude, /*sampling_frequency_in_hz=*/8000);
171 rtc::BufferT<int16_t> recording_buffer;
172
173 // Verify that the capturer doesn't create entries louder than than
174 // kAmplitude. Since the pulse generator alternates between writing
175 // zeroes and actual entries, we need to do the capturing twice.
176 capturer->Capture(&recording_buffer);
177 capturer->Capture(&recording_buffer);
178 int16_t max_sample =
179 *std::max_element(recording_buffer.begin(), recording_buffer.end());
180 EXPECT_LE(max_sample, kAmplitude);
181
182 // Increase the amplitude and verify that the samples can now be louder
183 // than the previous max.
184 capturer->SetMaxAmplitude(kAmplitude * 2);
185 capturer->Capture(&recording_buffer);
186 capturer->Capture(&recording_buffer);
187 max_sample =
188 *std::max_element(recording_buffer.begin(), recording_buffer.end());
189 EXPECT_GT(max_sample, kAmplitude);
190 }
191
192 } // namespace webrtc
193