Add a virtual beamforming audio device on ChromeOS.
[chromium-blink-merge.git] / content / renderer / media / media_stream_audio_processor_unittest.cc
blob20eb181240206123bcaa6e75fb764533747dd93d
1 // Copyright 2013 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.
5 #include <vector>
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/logging.h"
10 #include "base/memory/aligned_memory.h"
11 #include "base/path_service.h"
12 #include "base/time/time.h"
13 #include "content/public/common/media_stream_request.h"
14 #include "content/renderer/media/media_stream_audio_processor.h"
15 #include "content/renderer/media/media_stream_audio_processor_options.h"
16 #include "content/renderer/media/mock_media_constraint_factory.h"
17 #include "media/audio/audio_parameters.h"
18 #include "media/base/audio_bus.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
22 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
24 using ::testing::_;
25 using ::testing::AnyNumber;
26 using ::testing::AtLeast;
27 using ::testing::Return;
29 using media::AudioParameters;
31 namespace webrtc {
33 bool operator==(const webrtc::Point& lhs, const webrtc::Point& rhs) {
34 return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
37 } // namespace webrtc
39 namespace content {
41 namespace {
43 #if defined(ANDROID)
44 const int kAudioProcessingSampleRate = 16000;
45 #else
46 const int kAudioProcessingSampleRate = 48000;
47 #endif
48 const int kAudioProcessingNumberOfChannel = 1;
50 // The number of packers used for testing.
51 const int kNumberOfPacketsForTest = 100;
53 const int kMaxNumberOfPlayoutDataChannels = 2;
55 void ReadDataFromSpeechFile(char* data, int length) {
56 base::FilePath file;
57 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &file));
58 file = file.Append(FILE_PATH_LITERAL("media"))
59 .Append(FILE_PATH_LITERAL("test"))
60 .Append(FILE_PATH_LITERAL("data"))
61 .Append(FILE_PATH_LITERAL("speech_16b_stereo_48kHz.raw"));
62 DCHECK(base::PathExists(file));
63 int64 data_file_size64 = 0;
64 DCHECK(base::GetFileSize(file, &data_file_size64));
65 EXPECT_EQ(length, base::ReadFile(file, data, length));
66 DCHECK(data_file_size64 > length);
69 } // namespace
71 class MediaStreamAudioProcessorTest : public ::testing::Test {
72 public:
73 MediaStreamAudioProcessorTest()
74 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
75 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 512) {
78 protected:
79 // Helper method to save duplicated code.
80 void ProcessDataAndVerifyFormat(MediaStreamAudioProcessor* audio_processor,
81 int expected_output_sample_rate,
82 int expected_output_channels,
83 int expected_output_buffer_size) {
84 // Read the audio data from a file.
85 const media::AudioParameters& params = audio_processor->InputFormat();
86 const int packet_size =
87 params.frames_per_buffer() * 2 * params.channels();
88 const size_t length = packet_size * kNumberOfPacketsForTest;
89 scoped_ptr<char[]> capture_data(new char[length]);
90 ReadDataFromSpeechFile(capture_data.get(), length);
91 const int16* data_ptr = reinterpret_cast<const int16*>(capture_data.get());
92 scoped_ptr<media::AudioBus> data_bus = media::AudioBus::Create(
93 params.channels(), params.frames_per_buffer());
95 // |data_bus_playout| is used if the number of capture channels is larger
96 // that max allowed playout channels. |data_bus_playout_to_use| points to
97 // the AudioBus to use, either |data_bus| or |data_bus_playout|.
98 scoped_ptr<media::AudioBus> data_bus_playout;
99 media::AudioBus* data_bus_playout_to_use = data_bus.get();
100 if (params.channels() > kMaxNumberOfPlayoutDataChannels) {
101 data_bus_playout =
102 media::AudioBus::CreateWrapper(kMaxNumberOfPlayoutDataChannels);
103 data_bus_playout->set_frames(params.frames_per_buffer());
104 data_bus_playout_to_use = data_bus_playout.get();
107 const base::TimeDelta input_capture_delay =
108 base::TimeDelta::FromMilliseconds(20);
109 const base::TimeDelta output_buffer_duration =
110 expected_output_buffer_size * base::TimeDelta::FromSeconds(1) /
111 expected_output_sample_rate;
112 for (int i = 0; i < kNumberOfPacketsForTest; ++i) {
113 data_bus->FromInterleaved(data_ptr, data_bus->frames(), 2);
114 audio_processor->PushCaptureData(*data_bus, input_capture_delay);
116 // |audio_processor| does nothing when the audio processing is off in
117 // the processor.
118 webrtc::AudioProcessing* ap = audio_processor->audio_processing_.get();
119 #if defined(OS_ANDROID) || defined(OS_IOS)
120 const bool is_aec_enabled = ap && ap->echo_control_mobile()->is_enabled();
121 // AEC should be turned off for mobiles.
122 DCHECK(!ap || !ap->echo_cancellation()->is_enabled());
123 #else
124 const bool is_aec_enabled = ap && ap->echo_cancellation()->is_enabled();
125 #endif
126 if (is_aec_enabled) {
127 if (params.channels() > kMaxNumberOfPlayoutDataChannels) {
128 for (int i = 0; i < kMaxNumberOfPlayoutDataChannels; ++i) {
129 data_bus_playout->SetChannelData(
130 i, const_cast<float*>(data_bus->channel(i)));
133 audio_processor->OnPlayoutData(data_bus_playout_to_use,
134 params.sample_rate(), 10);
137 media::AudioBus* processed_data = nullptr;
138 base::TimeDelta capture_delay;
139 int new_volume = 0;
140 while (audio_processor->ProcessAndConsumeData(
141 255, false, &processed_data, &capture_delay, &new_volume)) {
142 EXPECT_TRUE(processed_data);
143 EXPECT_NEAR(input_capture_delay.InMillisecondsF(),
144 capture_delay.InMillisecondsF(),
145 output_buffer_duration.InMillisecondsF());
146 EXPECT_EQ(expected_output_sample_rate,
147 audio_processor->OutputFormat().sample_rate());
148 EXPECT_EQ(expected_output_channels,
149 audio_processor->OutputFormat().channels());
150 EXPECT_EQ(expected_output_buffer_size,
151 audio_processor->OutputFormat().frames_per_buffer());
154 data_ptr += params.frames_per_buffer() * params.channels();
158 void VerifyDefaultComponents(MediaStreamAudioProcessor* audio_processor) {
159 webrtc::AudioProcessing* audio_processing =
160 audio_processor->audio_processing_.get();
161 #if defined(OS_ANDROID)
162 EXPECT_TRUE(audio_processing->echo_control_mobile()->is_enabled());
163 EXPECT_TRUE(audio_processing->echo_control_mobile()->routing_mode() ==
164 webrtc::EchoControlMobile::kSpeakerphone);
165 EXPECT_FALSE(audio_processing->echo_cancellation()->is_enabled());
166 #elif !defined(OS_IOS)
167 EXPECT_TRUE(audio_processing->echo_cancellation()->is_enabled());
168 EXPECT_TRUE(audio_processing->echo_cancellation()->suppression_level() ==
169 webrtc::EchoCancellation::kHighSuppression);
170 EXPECT_TRUE(audio_processing->echo_cancellation()->are_metrics_enabled());
171 EXPECT_TRUE(
172 audio_processing->echo_cancellation()->is_delay_logging_enabled());
173 #endif
175 EXPECT_TRUE(audio_processing->noise_suppression()->is_enabled());
176 EXPECT_TRUE(audio_processing->noise_suppression()->level() ==
177 webrtc::NoiseSuppression::kHigh);
178 EXPECT_TRUE(audio_processing->high_pass_filter()->is_enabled());
179 EXPECT_TRUE(audio_processing->gain_control()->is_enabled());
180 #if defined(OS_ANDROID) || defined(OS_IOS)
181 EXPECT_TRUE(audio_processing->gain_control()->mode() ==
182 webrtc::GainControl::kFixedDigital);
183 EXPECT_FALSE(audio_processing->voice_detection()->is_enabled());
184 #else
185 EXPECT_TRUE(audio_processing->gain_control()->mode() ==
186 webrtc::GainControl::kAdaptiveAnalog);
187 EXPECT_TRUE(audio_processing->voice_detection()->is_enabled());
188 EXPECT_TRUE(audio_processing->voice_detection()->likelihood() ==
189 webrtc::VoiceDetection::kVeryLowLikelihood);
190 #endif
193 media::AudioParameters params_;
194 MediaStreamDevice::AudioDeviceParameters input_device_params_;
197 // Test crashing with ASAN on Android. crbug.com/468762
198 #if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
199 #define MAYBE_WithAudioProcessing DISABLED_WithAudioProcessing
200 #else
201 #define MAYBE_WithAudioProcessing WithAudioProcessing
202 #endif
203 TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
204 MockMediaConstraintFactory constraint_factory;
205 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
206 new WebRtcAudioDeviceImpl());
207 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
208 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
209 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
210 webrtc_audio_device.get()));
211 EXPECT_TRUE(audio_processor->has_audio_processing());
212 audio_processor->OnCaptureFormatChanged(params_);
213 VerifyDefaultComponents(audio_processor.get());
215 ProcessDataAndVerifyFormat(audio_processor.get(),
216 kAudioProcessingSampleRate,
217 kAudioProcessingNumberOfChannel,
218 kAudioProcessingSampleRate / 100);
219 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
220 // |audio_processor|.
221 audio_processor = NULL;
224 TEST_F(MediaStreamAudioProcessorTest, VerifyTabCaptureWithoutAudioProcessing) {
225 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
226 new WebRtcAudioDeviceImpl());
227 // Create MediaStreamAudioProcessor instance for kMediaStreamSourceTab source.
228 MockMediaConstraintFactory tab_constraint_factory;
229 const std::string tab_string = kMediaStreamSourceTab;
230 tab_constraint_factory.AddMandatory(kMediaStreamSource,
231 tab_string);
232 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
233 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
234 tab_constraint_factory.CreateWebMediaConstraints(),
235 input_device_params_, webrtc_audio_device.get()));
236 EXPECT_FALSE(audio_processor->has_audio_processing());
237 audio_processor->OnCaptureFormatChanged(params_);
239 ProcessDataAndVerifyFormat(audio_processor.get(),
240 params_.sample_rate(),
241 params_.channels(),
242 params_.sample_rate() / 100);
244 // Create MediaStreamAudioProcessor instance for kMediaStreamSourceSystem
245 // source.
246 MockMediaConstraintFactory system_constraint_factory;
247 const std::string system_string = kMediaStreamSourceSystem;
248 system_constraint_factory.AddMandatory(kMediaStreamSource,
249 system_string);
250 audio_processor = new rtc::RefCountedObject<MediaStreamAudioProcessor>(
251 system_constraint_factory.CreateWebMediaConstraints(),
252 input_device_params_, webrtc_audio_device.get());
253 EXPECT_FALSE(audio_processor->has_audio_processing());
255 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
256 // |audio_processor|.
257 audio_processor = NULL;
260 TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
261 // Turn off the default constraints and pass it to MediaStreamAudioProcessor.
262 MockMediaConstraintFactory constraint_factory;
263 constraint_factory.DisableDefaultAudioConstraints();
264 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
265 new WebRtcAudioDeviceImpl());
266 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
267 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
268 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
269 webrtc_audio_device.get()));
270 EXPECT_FALSE(audio_processor->has_audio_processing());
271 audio_processor->OnCaptureFormatChanged(params_);
273 ProcessDataAndVerifyFormat(audio_processor.get(),
274 params_.sample_rate(),
275 params_.channels(),
276 params_.sample_rate() / 100);
277 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
278 // |audio_processor|.
279 audio_processor = NULL;
282 TEST_F(MediaStreamAudioProcessorTest, VerifyConstraints) {
283 static const char* kDefaultAudioConstraints[] = {
284 MediaAudioConstraints::kEchoCancellation,
285 MediaAudioConstraints::kGoogAudioMirroring,
286 MediaAudioConstraints::kGoogAutoGainControl,
287 MediaAudioConstraints::kGoogEchoCancellation,
288 MediaAudioConstraints::kGoogExperimentalEchoCancellation,
289 MediaAudioConstraints::kGoogExperimentalAutoGainControl,
290 MediaAudioConstraints::kGoogExperimentalNoiseSuppression,
291 MediaAudioConstraints::kGoogHighpassFilter,
292 MediaAudioConstraints::kGoogNoiseSuppression,
293 MediaAudioConstraints::kGoogTypingNoiseDetection,
294 kMediaStreamAudioHotword
297 // Verify mandatory constraints.
298 for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
299 MockMediaConstraintFactory constraint_factory;
300 constraint_factory.AddMandatory(kDefaultAudioConstraints[i], false);
301 blink::WebMediaConstraints constraints =
302 constraint_factory.CreateWebMediaConstraints();
303 MediaAudioConstraints audio_constraints(constraints, 0);
304 EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
307 // Verify optional constraints.
308 for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
309 MockMediaConstraintFactory constraint_factory;
310 constraint_factory.AddOptional(kDefaultAudioConstraints[i], false);
311 blink::WebMediaConstraints constraints =
312 constraint_factory.CreateWebMediaConstraints();
313 MediaAudioConstraints audio_constraints(constraints, 0);
314 EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
318 // Verify echo cancellation is off when platform aec effect is on.
319 MockMediaConstraintFactory constraint_factory;
320 MediaAudioConstraints audio_constraints(
321 constraint_factory.CreateWebMediaConstraints(),
322 media::AudioParameters::ECHO_CANCELLER);
323 EXPECT_FALSE(audio_constraints.GetEchoCancellationProperty());
327 // Verify |kEchoCancellation| overwrite |kGoogEchoCancellation|.
328 MockMediaConstraintFactory constraint_factory_1;
329 constraint_factory_1.AddOptional(MediaAudioConstraints::kEchoCancellation,
330 true);
331 constraint_factory_1.AddOptional(
332 MediaAudioConstraints::kGoogEchoCancellation, false);
333 blink::WebMediaConstraints constraints_1 =
334 constraint_factory_1.CreateWebMediaConstraints();
335 MediaAudioConstraints audio_constraints_1(constraints_1, 0);
336 EXPECT_TRUE(audio_constraints_1.GetEchoCancellationProperty());
338 MockMediaConstraintFactory constraint_factory_2;
339 constraint_factory_2.AddOptional(MediaAudioConstraints::kEchoCancellation,
340 false);
341 constraint_factory_2.AddOptional(
342 MediaAudioConstraints::kGoogEchoCancellation, true);
343 blink::WebMediaConstraints constraints_2 =
344 constraint_factory_2.CreateWebMediaConstraints();
345 MediaAudioConstraints audio_constraints_2(constraints_2, 0);
346 EXPECT_FALSE(audio_constraints_2.GetEchoCancellationProperty());
350 // When |kEchoCancellation| is explicitly set to false, the default values
351 // for all the constraints are false.
352 MockMediaConstraintFactory constraint_factory;
353 constraint_factory.AddOptional(MediaAudioConstraints::kEchoCancellation,
354 false);
355 blink::WebMediaConstraints constraints =
356 constraint_factory.CreateWebMediaConstraints();
357 MediaAudioConstraints audio_constraints(constraints, 0);
358 for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
359 EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
364 // |kMediaStreamAudioHotword| is always off by default.
365 MockMediaConstraintFactory constraint_factory;
366 MediaAudioConstraints audio_constraints(
367 constraint_factory.CreateWebMediaConstraints(), 0);
368 EXPECT_FALSE(audio_constraints.GetProperty(kMediaStreamAudioHotword));
372 TEST_F(MediaStreamAudioProcessorTest, ValidateConstraints) {
373 MockMediaConstraintFactory constraint_factory;
374 const std::string dummy_constraint = "dummy";
375 constraint_factory.AddMandatory(dummy_constraint, true);
376 MediaAudioConstraints audio_constraints(
377 constraint_factory.CreateWebMediaConstraints(), 0);
378 EXPECT_FALSE(audio_constraints.IsValid());
381 MediaAudioConstraints MakeMediaAudioConstraints(
382 const MockMediaConstraintFactory& constraint_factory) {
383 return MediaAudioConstraints(constraint_factory.CreateWebMediaConstraints(),
384 AudioParameters::NO_EFFECTS);
387 TEST_F(MediaStreamAudioProcessorTest, SelectsConstraintsArrayGeometryIfExists) {
388 std::vector<webrtc::Point> constraints_geometry(1,
389 webrtc::Point(-0.02f, 0, 0));
390 constraints_geometry.push_back(webrtc::Point(0.02f, 0, 0));
392 std::vector<webrtc::Point> input_device_geometry(1, webrtc::Point(0, 0, 0));
393 input_device_geometry.push_back(webrtc::Point(0, 0.05f, 0));
396 // Both geometries empty.
397 MockMediaConstraintFactory constraint_factory;
398 MediaStreamDevice::AudioDeviceParameters input_params;
400 const auto& actual_geometry = GetArrayGeometryPreferringConstraints(
401 MakeMediaAudioConstraints(constraint_factory), input_params);
402 EXPECT_EQ(std::vector<webrtc::Point>(), actual_geometry);
405 // Constraints geometry empty.
406 MockMediaConstraintFactory constraint_factory;
407 MediaStreamDevice::AudioDeviceParameters input_params;
408 input_params.mic_positions.push_back(media::Point(0, 0, 0));
409 input_params.mic_positions.push_back(media::Point(0, 0.05f, 0));
411 const auto& actual_geometry = GetArrayGeometryPreferringConstraints(
412 MakeMediaAudioConstraints(constraint_factory), input_params);
413 EXPECT_EQ(input_device_geometry, actual_geometry);
416 // Input device geometry empty.
417 MockMediaConstraintFactory constraint_factory;
418 constraint_factory.AddOptional(MediaAudioConstraints::kGoogArrayGeometry,
419 std::string("-0.02 0 0 0.02 0 0"));
420 MediaStreamDevice::AudioDeviceParameters input_params;
422 const auto& actual_geometry = GetArrayGeometryPreferringConstraints(
423 MakeMediaAudioConstraints(constraint_factory), input_params);
424 EXPECT_EQ(constraints_geometry, actual_geometry);
427 // Both geometries existing.
428 MockMediaConstraintFactory constraint_factory;
429 constraint_factory.AddOptional(MediaAudioConstraints::kGoogArrayGeometry,
430 std::string("-0.02 0 0 0.02 0 0"));
431 MediaStreamDevice::AudioDeviceParameters input_params;
432 input_params.mic_positions.push_back(media::Point(0, 0, 0));
433 input_params.mic_positions.push_back(media::Point(0, 0.05f, 0));
435 // Constraints geometry is preferred.
436 const auto& actual_geometry = GetArrayGeometryPreferringConstraints(
437 MakeMediaAudioConstraints(constraint_factory), input_params);
438 EXPECT_EQ(constraints_geometry, actual_geometry);
442 // Test crashing with ASAN on Android. crbug.com/468762
443 #if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
444 #define MAYBE_TestAllSampleRates DISABLED_TestAllSampleRates
445 #else
446 #define MAYBE_TestAllSampleRates TestAllSampleRates
447 #endif
448 TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
449 MockMediaConstraintFactory constraint_factory;
450 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
451 new WebRtcAudioDeviceImpl());
452 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
453 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
454 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
455 webrtc_audio_device.get()));
456 EXPECT_TRUE(audio_processor->has_audio_processing());
458 static const int kSupportedSampleRates[] =
459 { 8000, 16000, 22050, 32000, 44100, 48000, 88200, 96000 };
460 for (size_t i = 0; i < arraysize(kSupportedSampleRates); ++i) {
461 int buffer_size = (kSupportedSampleRates[i] / 100) < 128 ?
462 kSupportedSampleRates[i] / 100 : 128;
463 media::AudioParameters params(
464 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
465 media::CHANNEL_LAYOUT_STEREO, kSupportedSampleRates[i], 16,
466 buffer_size);
467 audio_processor->OnCaptureFormatChanged(params);
468 VerifyDefaultComponents(audio_processor.get());
470 ProcessDataAndVerifyFormat(audio_processor.get(),
471 kAudioProcessingSampleRate,
472 kAudioProcessingNumberOfChannel,
473 kAudioProcessingSampleRate / 100);
476 // Set |audio_processor| to NULL to make sure |webrtc_audio_device|
477 // outlives |audio_processor|.
478 audio_processor = NULL;
481 // Test that if we have an AEC dump message filter created, we are getting it
482 // correctly in MSAP. Any IPC messages will be deleted since no sender in the
483 // filter will be created.
484 TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
485 base::MessageLoopForUI message_loop;
486 scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_(
487 new AecDumpMessageFilter(message_loop.task_runner(),
488 message_loop.task_runner()));
490 MockMediaConstraintFactory constraint_factory;
491 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
492 new WebRtcAudioDeviceImpl());
493 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
494 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
495 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
496 webrtc_audio_device.get()));
498 EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get());
500 audio_processor = NULL;
503 TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
504 // Set up the correct constraints to turn off the audio processing and turn
505 // on the stereo channels mirroring.
506 MockMediaConstraintFactory constraint_factory;
507 constraint_factory.AddMandatory(MediaAudioConstraints::kEchoCancellation,
508 false);
509 constraint_factory.AddMandatory(MediaAudioConstraints::kGoogAudioMirroring,
510 true);
511 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
512 new WebRtcAudioDeviceImpl());
513 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
514 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
515 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
516 webrtc_audio_device.get()));
517 EXPECT_FALSE(audio_processor->has_audio_processing());
518 const media::AudioParameters source_params(
519 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
520 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 480);
521 audio_processor->OnCaptureFormatChanged(source_params);
522 EXPECT_EQ(audio_processor->OutputFormat().channels(), 2);
524 // Construct left and right channels, and assign different values to the
525 // first data of the left channel and right channel.
526 const int size = media::AudioBus::CalculateMemorySize(source_params);
527 scoped_ptr<float, base::AlignedFreeDeleter> left_channel(
528 static_cast<float*>(base::AlignedAlloc(size, 32)));
529 scoped_ptr<float, base::AlignedFreeDeleter> right_channel(
530 static_cast<float*>(base::AlignedAlloc(size, 32)));
531 scoped_ptr<media::AudioBus> wrapper = media::AudioBus::CreateWrapper(
532 source_params.channels());
533 wrapper->set_frames(source_params.frames_per_buffer());
534 wrapper->SetChannelData(0, left_channel.get());
535 wrapper->SetChannelData(1, right_channel.get());
536 wrapper->Zero();
537 float* left_channel_ptr = left_channel.get();
538 left_channel_ptr[0] = 1.0f;
540 // Run the test consecutively to make sure the stereo channels are not
541 // flipped back and forth.
542 static const int kNumberOfPacketsForTest = 100;
543 const base::TimeDelta pushed_capture_delay =
544 base::TimeDelta::FromMilliseconds(42);
545 for (int i = 0; i < kNumberOfPacketsForTest; ++i) {
546 audio_processor->PushCaptureData(*wrapper, pushed_capture_delay);
548 media::AudioBus* processed_data = nullptr;
549 base::TimeDelta capture_delay;
550 int new_volume = 0;
551 EXPECT_TRUE(audio_processor->ProcessAndConsumeData(
552 0, false, &processed_data, &capture_delay, &new_volume));
553 EXPECT_TRUE(processed_data);
554 EXPECT_EQ(processed_data->channel(0)[0], 0);
555 EXPECT_NE(processed_data->channel(1)[0], 0);
556 EXPECT_EQ(pushed_capture_delay, capture_delay);
559 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
560 // |audio_processor|.
561 audio_processor = NULL;
564 // Disabled on android clang builds due to crbug.com/470499
565 #if defined(__clang__) && defined(OS_ANDROID)
566 #define MAYBE_TestWithKeyboardMicChannel DISABLED_TestWithKeyboardMicChannel
567 #else
568 #define MAYBE_TestWithKeyboardMicChannel TestWithKeyboardMicChannel
569 #endif
571 TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
572 MockMediaConstraintFactory constraint_factory;
573 constraint_factory.AddMandatory(
574 MediaAudioConstraints::kGoogExperimentalNoiseSuppression, true);
575 scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
576 new WebRtcAudioDeviceImpl());
577 scoped_refptr<MediaStreamAudioProcessor> audio_processor(
578 new rtc::RefCountedObject<MediaStreamAudioProcessor>(
579 constraint_factory.CreateWebMediaConstraints(), input_device_params_,
580 webrtc_audio_device.get()));
581 EXPECT_TRUE(audio_processor->has_audio_processing());
583 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
584 media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC,
585 48000, 16, 512);
586 audio_processor->OnCaptureFormatChanged(params);
588 ProcessDataAndVerifyFormat(audio_processor.get(),
589 kAudioProcessingSampleRate,
590 kAudioProcessingNumberOfChannel,
591 kAudioProcessingSampleRate / 100);
592 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
593 // |audio_processor|.
594 audio_processor = NULL;
597 } // namespace content