Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: media/audio/audio_debug_recording_helper_unittest.cc

Issue 2582703003: Audio output debug recording. (Closed)
Patch Set: Code review. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/audio/audio_debug_recording_helper.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/test/test_message_loop.h"
14 #include "media/base/audio_bus.h"
15 #include "media/base/audio_sample_types.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using testing::_;
20 using testing::Return;
21
22 #if defined(OS_WIN)
23 #define IntToStringType base::IntToString16
24 #else
25 #define IntToStringType base::IntToString
26 #endif
27
28 namespace media {
29
30 namespace {
31
32 // The base file path.
33 const base::FilePath::CharType kBaseFilePath[] = FILE_PATH_LITERAL("file_path");
34
35 // The filename extension the mock should return in GetFileNameExtension().
36 const base::FilePath::CharType kFileNameExtension[] = FILE_PATH_LITERAL("wav");
37
38 } // namespace
39
40 // Mock class for the audio file writer that the helper wraps.
41 class MockAudioDebugFileWriter : public AudioDebugFileWriter {
42 public:
43 MockAudioDebugFileWriter(
44 const AudioParameters& params,
45 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
46 : AudioDebugFileWriter(params, std::move(file_task_runner)),
47 reference_data_(nullptr) {}
48 ~MockAudioDebugFileWriter() override {}
49
50 MOCK_METHOD1(Start, void(const base::FilePath&));
51 MOCK_METHOD0(Stop, void());
52
53 // Functions with move-only types as arguments can't be mocked directly, so
54 // we pass on to DoWrite(). Also, we can verify the data this way.
55 MOCK_METHOD1(DoWrite, void(AudioBus*));
56 void Write(std::unique_ptr<AudioBus> data) override {
57 CHECK(reference_data_);
58 EXPECT_EQ(reference_data_->channels(), data->channels());
59 EXPECT_EQ(reference_data_->frames(), data->frames());
60 for (int i = 0; i < data->channels(); ++i) {
61 float* data_ptr = data->channel(i);
62 float* ref_data_ptr = reference_data_->channel(i);
63 for (int j = 0; j < data->frames(); ++j, ++data_ptr, ++ref_data_ptr)
64 EXPECT_EQ(*ref_data_ptr, *data_ptr);
65 }
66 DoWrite(data.get());
67 }
68
69 MOCK_METHOD0(WillWrite, bool());
70 MOCK_METHOD0(GetFileNameExtension, const base::FilePath::CharType*());
71
72 // Set reference data to compare against. Must be called before Write() is
73 // called.
74 void SetReferenceData(AudioBus* reference_data) {
75 EXPECT_EQ(params_.channels(), reference_data->channels());
76 EXPECT_EQ(params_.frames_per_buffer(), reference_data->frames());
77 reference_data_ = reference_data;
78 }
79
80 private:
81 AudioBus* reference_data_;
82
83 DISALLOW_COPY_AND_ASSIGN(MockAudioDebugFileWriter);
84 };
85
86 // Sub-class of the helper that overrides the CreateAudioDebugFileWriter
87 // function to create the above mock instead.
88 class AudioDebugRecordingHelperUnderTest : public AudioDebugRecordingHelper {
89 public:
90 AudioDebugRecordingHelperUnderTest(
91 const AudioParameters& params,
92 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
93 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
94 base::OnceClosure on_destruction_closure)
95 : AudioDebugRecordingHelper(params,
96 std::move(task_runner),
97 std::move(file_task_runner),
98 std::move(on_destruction_closure)) {}
99 ~AudioDebugRecordingHelperUnderTest() override {}
100
101 private:
102 // Creates the mock writer. After the mock writer is returned, we always
103 // expect GetFileNameExtension() and Start() to be called on it by the helper.
104 std::unique_ptr<AudioDebugFileWriter> CreateAudioDebugFileWriter(
105 const AudioParameters& params,
106 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) override {
107 MockAudioDebugFileWriter* writer =
108 new MockAudioDebugFileWriter(params, std::move(file_task_runner));
109 EXPECT_CALL(*writer, GetFileNameExtension())
110 .WillOnce(Return(kFileNameExtension));
111 base::FilePath expected_file_path =
112 base::FilePath(kBaseFilePath).AddExtension(kFileNameExtension);
113 EXPECT_CALL(*writer, Start(expected_file_path));
114 return base::WrapUnique<AudioDebugFileWriter>(writer);
115 }
116
117 DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingHelperUnderTest);
118 };
119
120 // The test fixture.
121 class AudioDebugRecordingHelperTest : public ::testing::Test {
122 public:
123 AudioDebugRecordingHelperTest() : file_path_(kBaseFilePath) {}
124
125 ~AudioDebugRecordingHelperTest() override {}
126
127 // Helper function that creates a recording helper.
128 std::unique_ptr<AudioDebugRecordingHelper> CreateRecordingHelper(
129 const AudioParameters& params,
130 base::OnceClosure on_destruction_closure) {
131 return base::MakeUnique<AudioDebugRecordingHelperUnderTest>(
132 params, message_loop_.task_runner(), message_loop_.task_runner(),
133 std::move(on_destruction_closure));
134 }
135
136 // Helper function that unsets the mock writer pointer after disabling.
137 void DisableDebugRecording(AudioDebugRecordingHelper* recording_helper) {
138 recording_helper->DisableDebugRecording();
139 }
140
141 MOCK_METHOD0(OnAudioDebugRecordingHelperDestruction, void());
142
143 protected:
144 base::FilePath file_path_;
145
146 base::TestMessageLoop message_loop_;
147
148 private:
149 DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingHelperTest);
150 };
151
152 // Creates a helper with an on destrcution closure, and verifies that it's
153 // run.
154 TEST_F(AudioDebugRecordingHelperTest, TestDestructionClosure) {
155 const AudioParameters params;
156 std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
157 CreateRecordingHelper(
158 params, base::BindOnce(&AudioDebugRecordingHelperTest::
159 OnAudioDebugRecordingHelperDestruction,
160 base::Unretained(this)));
161
162 EXPECT_CALL(*this, OnAudioDebugRecordingHelperDestruction());
163 }
164
165 // Verifies that disable can be called without being enabled.
166 TEST_F(AudioDebugRecordingHelperTest, OnlyDisable) {
167 const AudioParameters params;
168 std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
169 CreateRecordingHelper(params, base::OnceClosure());
170
171 recording_helper->DisableDebugRecording();
172 }
173
174 TEST_F(AudioDebugRecordingHelperTest, EnableDisable) {
175 const AudioParameters params;
176 std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
177 CreateRecordingHelper(params, base::OnceClosure());
178
179 recording_helper->EnableDebugRecording(file_path_);
180 EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
181 recording_helper->debug_writer_.get()),
182 Stop());
183 DisableDebugRecording(recording_helper.get());
184
185 recording_helper->EnableDebugRecording(file_path_);
186 EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
187 recording_helper->debug_writer_.get()),
188 Stop());
189 DisableDebugRecording(recording_helper.get());
190 }
191
192 TEST_F(AudioDebugRecordingHelperTest, OnData) {
193 // Only channel layout and frames per buffer is used in the file writer and
194 // AudioBus, the other parameters are ignored.
195 const int number_of_frames = 100;
196 const AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
197 ChannelLayout::CHANNEL_LAYOUT_STEREO, 0, 0,
198 number_of_frames);
199
200 // Setup some data.
201 const int number_of_samples = number_of_frames * params.channels();
202 const float step = std::numeric_limits<int16_t>::max() / number_of_frames;
203 std::unique_ptr<float[]> source_data(new float[number_of_samples]);
204 for (float i = 0; i < number_of_samples; ++i)
205 source_data[i] = i * step;
206 std::unique_ptr<AudioBus> audio_bus = AudioBus::Create(params);
207 audio_bus->FromInterleaved<Float32SampleTypeTraits>(source_data.get(),
208 number_of_frames);
209
210 std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
211 CreateRecordingHelper(params, base::OnceClosure());
212
213 // Should not do anything.
214 recording_helper->OnData(audio_bus.get());
215
216 recording_helper->EnableDebugRecording(file_path_);
217 MockAudioDebugFileWriter* mock_audio_file_writer =
218 static_cast<MockAudioDebugFileWriter*>(
219 recording_helper->debug_writer_.get());
220 mock_audio_file_writer->SetReferenceData(audio_bus.get());
221
222 EXPECT_CALL(*mock_audio_file_writer, DoWrite(_));
223 recording_helper->OnData(audio_bus.get());
224 base::RunLoop().RunUntilIdle();
225
226 EXPECT_CALL(*mock_audio_file_writer, Stop());
227 DisableDebugRecording(recording_helper.get());
228
229 // Make sure we clear the loop before enabling again.
230 base::RunLoop().RunUntilIdle();
231
232 // Enable again, this time with two OnData() calls, one OnData() call
233 // without running the message loop until after disabling, and one call after
234 // disabling.
235 recording_helper->EnableDebugRecording(file_path_);
236 mock_audio_file_writer = static_cast<MockAudioDebugFileWriter*>(
237 recording_helper->debug_writer_.get());
238 mock_audio_file_writer->SetReferenceData(audio_bus.get());
239
240 EXPECT_CALL(*mock_audio_file_writer, DoWrite(_)).Times(2);
241 recording_helper->OnData(audio_bus.get());
242 recording_helper->OnData(audio_bus.get());
243 base::RunLoop().RunUntilIdle();
244
245 // This call should not yield a DoWrite() call on the mock, since the message
246 // loop isn't run until after disabling. WillWrite() is expected since
247 // recording is enabled.
248 recording_helper->OnData(audio_bus.get());
249
250 EXPECT_CALL(*mock_audio_file_writer, Stop());
251 DisableDebugRecording(recording_helper.get());
252
253 // This call should not yield a DoWrite() call on the mock either.
254 recording_helper->OnData(audio_bus.get());
255 base::RunLoop().RunUntilIdle();
256 }
257
258 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_debug_recording_helper.cc ('k') | media/audio/audio_debug_recording_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698