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

Side by Side Diff: components/audio_modem/audio_recorder_unittest.cc

Issue 2131993002: Delete the audio modem and copresence private APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@eol
Patch Set: Sync again Created 4 years, 5 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
« no previous file with comments | « components/audio_modem/audio_recorder_impl.cc ('k') | components/audio_modem/constants.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "components/audio_modem/audio_recorder.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h"
15 #include "base/run_loop.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "build/build_config.h"
18 #include "components/audio_modem/audio_recorder_impl.h"
19 #include "components/audio_modem/public/audio_modem_types.h"
20 #include "components/audio_modem/test/random_samples.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "media/audio/audio_device_description.h"
23 #include "media/audio/audio_manager.h"
24 #include "media/base/audio_bus.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace {
28
29 const size_t kSomeNumber = 0x9999;
30
31 class TestAudioInputStream : public media::AudioInputStream {
32 public:
33 TestAudioInputStream(const media::AudioParameters& params,
34 const std::vector<float*> channel_data,
35 size_t samples)
36 : callback_(nullptr), params_(params) {
37 buffer_ = media::AudioBus::CreateWrapper(2);
38 for (size_t i = 0; i < channel_data.size(); ++i)
39 buffer_->SetChannelData(i, channel_data[i]);
40 buffer_->set_frames(samples);
41 }
42
43 ~TestAudioInputStream() override {}
44
45 bool Open() override { return true; }
46 void Start(AudioInputCallback* callback) override {
47 DCHECK(callback);
48 callback_ = callback;
49 media::AudioManager::Get()->GetTaskRunner()->PostTask(
50 FROM_HERE,
51 base::Bind(&TestAudioInputStream::SimulateRecording,
52 base::Unretained(this)));
53 }
54 void Stop() override {}
55 void Close() override {}
56 double GetMaxVolume() override { return 1.0; }
57 void SetVolume(double volume) override {}
58 double GetVolume() override { return 1.0; }
59 bool SetAutomaticGainControl(bool enabled) override { return false; }
60 bool GetAutomaticGainControl() override { return true; }
61 bool IsMuted() override { return false; }
62
63 private:
64 void SimulateRecording() {
65 const int fpb = params_.frames_per_buffer();
66 for (int i = 0; i < buffer_->frames() / fpb; ++i) {
67 std::unique_ptr<media::AudioBus> source = media::AudioBus::Create(2, fpb);
68 buffer_->CopyPartialFramesTo(i * fpb, fpb, 0, source.get());
69 callback_->OnData(this, source.get(), fpb, 1.0);
70 }
71 }
72
73 AudioInputCallback* callback_;
74 media::AudioParameters params_;
75 std::unique_ptr<media::AudioBus> buffer_;
76
77 DISALLOW_COPY_AND_ASSIGN(TestAudioInputStream);
78 };
79
80 } // namespace
81
82 namespace audio_modem {
83
84 class AudioRecorderTest : public testing::Test {
85 public:
86 AudioRecorderTest() : total_samples_(0), recorder_(nullptr) {
87 audio_manager_ = media::AudioManager::CreateForTesting(
88 base::ThreadTaskRunnerHandle::Get());
89 base::RunLoop().RunUntilIdle();
90 }
91
92 ~AudioRecorderTest() override {
93 DeleteRecorder();
94 for (size_t i = 0; i < channel_data_.size(); ++i)
95 base::AlignedFree(channel_data_[i]);
96 }
97
98 void CreateSimpleRecorder() {
99 // If we have input devices, we'll create a recorder which uses a real
100 // input stream, if not, we'll create a recorder which uses our mock input
101 // stream.
102 if (media::AudioManager::Get()->HasAudioInputDevices()) {
103 DeleteRecorder();
104 recorder_ = new AudioRecorderImpl();
105 recorder_->Initialize(base::Bind(&AudioRecorderTest::DecodeSamples,
106 base::Unretained(this)));
107 base::RunLoop().RunUntilIdle();
108 } else {
109 CreateRecorder(kSomeNumber);
110 }
111 }
112
113 void CreateRecorder(size_t samples) {
114 DeleteRecorder();
115
116 params_ = media::AudioManager::Get()->GetInputStreamParameters(
117 media::AudioDeviceDescription::kDefaultDeviceId);
118
119 channel_data_.clear();
120 channel_data_.push_back(GenerateSamples(0x1337, samples));
121 channel_data_.push_back(GenerateSamples(0x7331, samples));
122
123 total_samples_ = samples;
124
125 recorder_ = new AudioRecorderImpl();
126 recorder_->set_input_stream_for_testing(
127 new TestAudioInputStream(params_, channel_data_, samples));
128 recorder_->set_params_for_testing(new media::AudioParameters(params_));
129 recorder_->Initialize(
130 base::Bind(&AudioRecorderTest::DecodeSamples, base::Unretained(this)));
131 base::RunLoop().RunUntilIdle();
132 }
133
134 void DeleteRecorder() {
135 if (!recorder_)
136 return;
137 recorder_->Finalize();
138 recorder_ = nullptr;
139 base::RunLoop().RunUntilIdle();
140 }
141
142 void RecordAndVerifySamples() {
143 received_samples_.clear();
144 run_loop_.reset(new base::RunLoop());
145 recorder_->Record();
146 run_loop_->Run();
147 }
148
149 void DecodeSamples(const std::string& samples) {
150 received_samples_ += samples;
151 // We expect one less decode than our total samples would ideally have
152 // triggered since we process data in 4k chunks. So our sample processing
153 // will never rarely be perfectly aligned with 0.5s worth of samples, hence
154 // we will almost always run with a buffer of leftover samples that will
155 // not get sent to this callback since the recorder will be waiting for
156 // more data.
157 const size_t decode_buffer = params_.sample_rate() / 2; // 0.5s
158 const size_t expected_samples =
159 (total_samples_ / decode_buffer - 1) * decode_buffer;
160 const size_t expected_samples_size =
161 expected_samples * sizeof(float) * params_.channels();
162 if (received_samples_.size() == expected_samples_size) {
163 VerifySamples();
164 run_loop_->Quit();
165 }
166 }
167
168 void VerifySamples() {
169 int differences = 0;
170
171 float* buffer_view =
172 reinterpret_cast<float*>(string_as_array(&received_samples_));
173 const int channels = params_.channels();
174 const int frames =
175 received_samples_.size() / sizeof(float) / params_.channels();
176 for (int ch = 0; ch < channels; ++ch) {
177 for (int si = 0, di = ch; si < frames; ++si, di += channels)
178 differences += (buffer_view[di] != channel_data_[ch][si]);
179 }
180
181 ASSERT_EQ(0, differences);
182 }
183
184 protected:
185 float* GenerateSamples(int random_seed, size_t size) {
186 float* samples = static_cast<float*>(base::AlignedAlloc(
187 size * sizeof(float), media::AudioBus::kChannelAlignment));
188 PopulateSamples(0x1337, size, samples);
189 return samples;
190 }
191 bool IsRecording() {
192 base::RunLoop().RunUntilIdle();
193 return recorder_->is_recording_;
194 }
195
196 content::TestBrowserThreadBundle thread_bundle_;
197 media::ScopedAudioManagerPtr audio_manager_;
198
199 std::vector<float*> channel_data_;
200 media::AudioParameters params_;
201 size_t total_samples_;
202
203 // Deleted by calling Finalize() on the object.
204 AudioRecorderImpl* recorder_;
205
206 std::string received_samples_;
207
208 std::unique_ptr<base::RunLoop> run_loop_;
209 };
210
211
212 // http://crbug.com/463854
213 #if defined(OS_MACOSX)
214 #define MAYBE_BasicRecordAndStop DISABLED_BasicRecordAndStop
215 #else
216 #define MAYBE_BasicRecordAndStop BasicRecordAndStop
217 #endif
218
219 TEST_F(AudioRecorderTest, MAYBE_BasicRecordAndStop) {
220 CreateSimpleRecorder();
221
222 recorder_->Record();
223 EXPECT_TRUE(IsRecording());
224
225 recorder_->Stop();
226 EXPECT_FALSE(IsRecording());
227
228 recorder_->Record();
229 EXPECT_TRUE(IsRecording());
230
231 recorder_->Stop();
232 EXPECT_FALSE(IsRecording());
233
234 recorder_->Record();
235 EXPECT_TRUE(IsRecording());
236
237 recorder_->Stop();
238 EXPECT_FALSE(IsRecording());
239
240 DeleteRecorder();
241 }
242
243 // http://crbug.com/460685
244 #if defined(OS_MACOSX)
245 #define MAYBE_OutOfOrderRecordAndStopMultiple \
246 DISABLED_OutOfOrderRecordAndStopMultiple
247 #else
248 #define MAYBE_OutOfOrderRecordAndStopMultiple \
249 OutOfOrderRecordAndStopMultiple
250 #endif
251
252 TEST_F(AudioRecorderTest, MAYBE_OutOfOrderRecordAndStopMultiple) {
253 CreateSimpleRecorder();
254
255 recorder_->Stop();
256 recorder_->Stop();
257 recorder_->Stop();
258 EXPECT_FALSE(IsRecording());
259
260 recorder_->Record();
261 recorder_->Record();
262 EXPECT_TRUE(IsRecording());
263
264 recorder_->Stop();
265 recorder_->Stop();
266 EXPECT_FALSE(IsRecording());
267
268 DeleteRecorder();
269 }
270
271 TEST_F(AudioRecorderTest, RecordingEndToEnd) {
272 const int kNumSamples = 48000 * 3;
273 CreateRecorder(kNumSamples);
274
275 RecordAndVerifySamples();
276
277 DeleteRecorder();
278 }
279
280 // TODO(rkc): Add tests with recording different sample rates.
281
282 } // namespace audio_modem
OLDNEW
« no previous file with comments | « components/audio_modem/audio_recorder_impl.cc ('k') | components/audio_modem/constants.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698