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.
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"
25 using ::testing::AnyNumber
;
26 using ::testing::AtLeast
;
27 using ::testing::Return
;
34 const int kAudioProcessingSampleRate
= 16000;
36 const int kAudioProcessingSampleRate
= 48000;
38 const int kAudioProcessingNumberOfChannel
= 1;
40 // The number of packers used for testing.
41 const int kNumberOfPacketsForTest
= 100;
43 const int kMaxNumberOfPlayoutDataChannels
= 2;
45 void ReadDataFromSpeechFile(char* data
, int length
) {
47 CHECK(PathService::Get(base::DIR_SOURCE_ROOT
, &file
));
48 file
= file
.Append(FILE_PATH_LITERAL("media"))
49 .Append(FILE_PATH_LITERAL("test"))
50 .Append(FILE_PATH_LITERAL("data"))
51 .Append(FILE_PATH_LITERAL("speech_16b_stereo_48kHz.raw"));
52 DCHECK(base::PathExists(file
));
53 int64 data_file_size64
= 0;
54 DCHECK(base::GetFileSize(file
, &data_file_size64
));
55 EXPECT_EQ(length
, base::ReadFile(file
, data
, length
));
56 DCHECK(data_file_size64
> length
);
61 class MediaStreamAudioProcessorTest
: public ::testing::Test
{
63 MediaStreamAudioProcessorTest()
64 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
65 media::CHANNEL_LAYOUT_STEREO
, 48000, 16, 512) {
69 // Helper method to save duplicated code.
70 void ProcessDataAndVerifyFormat(MediaStreamAudioProcessor
* audio_processor
,
71 int expected_output_sample_rate
,
72 int expected_output_channels
,
73 int expected_output_buffer_size
) {
74 // Read the audio data from a file.
75 const media::AudioParameters
& params
= audio_processor
->InputFormat();
76 const int packet_size
=
77 params
.frames_per_buffer() * 2 * params
.channels();
78 const size_t length
= packet_size
* kNumberOfPacketsForTest
;
79 scoped_ptr
<char[]> capture_data(new char[length
]);
80 ReadDataFromSpeechFile(capture_data
.get(), length
);
81 const int16
* data_ptr
= reinterpret_cast<const int16
*>(capture_data
.get());
82 scoped_ptr
<media::AudioBus
> data_bus
= media::AudioBus::Create(
83 params
.channels(), params
.frames_per_buffer());
85 // |data_bus_playout| is used if the number of capture channels is larger
86 // that max allowed playout channels. |data_bus_playout_to_use| points to
87 // the AudioBus to use, either |data_bus| or |data_bus_playout|.
88 scoped_ptr
<media::AudioBus
> data_bus_playout
;
89 media::AudioBus
* data_bus_playout_to_use
= data_bus
.get();
90 if (params
.channels() > kMaxNumberOfPlayoutDataChannels
) {
92 media::AudioBus::CreateWrapper(kMaxNumberOfPlayoutDataChannels
);
93 data_bus_playout
->set_frames(params
.frames_per_buffer());
94 data_bus_playout_to_use
= data_bus_playout
.get();
97 const base::TimeDelta input_capture_delay
=
98 base::TimeDelta::FromMilliseconds(20);
99 const base::TimeDelta output_buffer_duration
=
100 expected_output_buffer_size
* base::TimeDelta::FromSeconds(1) /
101 expected_output_sample_rate
;
102 for (int i
= 0; i
< kNumberOfPacketsForTest
; ++i
) {
103 data_bus
->FromInterleaved(data_ptr
, data_bus
->frames(), 2);
104 audio_processor
->PushCaptureData(*data_bus
, input_capture_delay
);
106 // |audio_processor| does nothing when the audio processing is off in
108 webrtc::AudioProcessing
* ap
= audio_processor
->audio_processing_
.get();
109 #if defined(OS_ANDROID) || defined(OS_IOS)
110 const bool is_aec_enabled
= ap
&& ap
->echo_control_mobile()->is_enabled();
111 // AEC should be turned off for mobiles.
112 DCHECK(!ap
|| !ap
->echo_cancellation()->is_enabled());
114 const bool is_aec_enabled
= ap
&& ap
->echo_cancellation()->is_enabled();
116 if (is_aec_enabled
) {
117 if (params
.channels() > kMaxNumberOfPlayoutDataChannels
) {
118 for (int i
= 0; i
< kMaxNumberOfPlayoutDataChannels
; ++i
) {
119 data_bus_playout
->SetChannelData(
120 i
, const_cast<float*>(data_bus
->channel(i
)));
123 audio_processor
->OnPlayoutData(data_bus_playout_to_use
,
124 params
.sample_rate(), 10);
127 media::AudioBus
* processed_data
= nullptr;
128 base::TimeDelta capture_delay
;
130 while (audio_processor
->ProcessAndConsumeData(
131 255, false, &processed_data
, &capture_delay
, &new_volume
)) {
132 EXPECT_TRUE(processed_data
);
133 EXPECT_NEAR(input_capture_delay
.InMillisecondsF(),
134 capture_delay
.InMillisecondsF(),
135 output_buffer_duration
.InMillisecondsF());
136 EXPECT_EQ(audio_processor
->OutputFormat().sample_rate(),
137 expected_output_sample_rate
);
138 EXPECT_EQ(audio_processor
->OutputFormat().channels(),
139 expected_output_channels
);
140 EXPECT_EQ(audio_processor
->OutputFormat().frames_per_buffer(),
141 expected_output_buffer_size
);
144 data_ptr
+= params
.frames_per_buffer() * params
.channels();
148 void VerifyDefaultComponents(MediaStreamAudioProcessor
* audio_processor
) {
149 webrtc::AudioProcessing
* audio_processing
=
150 audio_processor
->audio_processing_
.get();
151 #if defined(OS_ANDROID)
152 EXPECT_TRUE(audio_processing
->echo_control_mobile()->is_enabled());
153 EXPECT_TRUE(audio_processing
->echo_control_mobile()->routing_mode() ==
154 webrtc::EchoControlMobile::kSpeakerphone
);
155 EXPECT_FALSE(audio_processing
->echo_cancellation()->is_enabled());
156 #elif !defined(OS_IOS)
157 EXPECT_TRUE(audio_processing
->echo_cancellation()->is_enabled());
158 EXPECT_TRUE(audio_processing
->echo_cancellation()->suppression_level() ==
159 webrtc::EchoCancellation::kHighSuppression
);
160 EXPECT_TRUE(audio_processing
->echo_cancellation()->are_metrics_enabled());
162 audio_processing
->echo_cancellation()->is_delay_logging_enabled());
165 EXPECT_TRUE(audio_processing
->noise_suppression()->is_enabled());
166 EXPECT_TRUE(audio_processing
->noise_suppression()->level() ==
167 webrtc::NoiseSuppression::kHigh
);
168 EXPECT_TRUE(audio_processing
->high_pass_filter()->is_enabled());
169 EXPECT_TRUE(audio_processing
->gain_control()->is_enabled());
170 #if defined(OS_ANDROID) || defined(OS_IOS)
171 EXPECT_TRUE(audio_processing
->gain_control()->mode() ==
172 webrtc::GainControl::kFixedDigital
);
173 EXPECT_FALSE(audio_processing
->voice_detection()->is_enabled());
175 EXPECT_TRUE(audio_processing
->gain_control()->mode() ==
176 webrtc::GainControl::kAdaptiveAnalog
);
177 EXPECT_TRUE(audio_processing
->voice_detection()->is_enabled());
178 EXPECT_TRUE(audio_processing
->voice_detection()->likelihood() ==
179 webrtc::VoiceDetection::kVeryLowLikelihood
);
183 media::AudioParameters params_
;
186 // Test crashing with ASAN on Android. crbug.com/468762
187 #if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
188 #define MAYBE_WithAudioProcessing DISABLED_WithAudioProcessing
190 #define MAYBE_WithAudioProcessing WithAudioProcessing
192 TEST_F(MediaStreamAudioProcessorTest
, MAYBE_WithAudioProcessing
) {
193 MockMediaConstraintFactory constraint_factory
;
194 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
195 new WebRtcAudioDeviceImpl());
196 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
197 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
198 constraint_factory
.CreateWebMediaConstraints(), 0,
199 webrtc_audio_device
.get()));
200 EXPECT_TRUE(audio_processor
->has_audio_processing());
201 audio_processor
->OnCaptureFormatChanged(params_
);
202 VerifyDefaultComponents(audio_processor
.get());
204 ProcessDataAndVerifyFormat(audio_processor
.get(),
205 kAudioProcessingSampleRate
,
206 kAudioProcessingNumberOfChannel
,
207 kAudioProcessingSampleRate
/ 100);
208 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
209 // |audio_processor|.
210 audio_processor
= NULL
;
213 TEST_F(MediaStreamAudioProcessorTest
, VerifyTabCaptureWithoutAudioProcessing
) {
214 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
215 new WebRtcAudioDeviceImpl());
216 // Create MediaStreamAudioProcessor instance for kMediaStreamSourceTab source.
217 MockMediaConstraintFactory tab_constraint_factory
;
218 const std::string tab_string
= kMediaStreamSourceTab
;
219 tab_constraint_factory
.AddMandatory(kMediaStreamSource
,
221 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
222 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
223 tab_constraint_factory
.CreateWebMediaConstraints(), 0,
224 webrtc_audio_device
.get()));
225 EXPECT_FALSE(audio_processor
->has_audio_processing());
226 audio_processor
->OnCaptureFormatChanged(params_
);
228 ProcessDataAndVerifyFormat(audio_processor
.get(),
229 params_
.sample_rate(),
231 params_
.sample_rate() / 100);
233 // Create MediaStreamAudioProcessor instance for kMediaStreamSourceSystem
235 MockMediaConstraintFactory system_constraint_factory
;
236 const std::string system_string
= kMediaStreamSourceSystem
;
237 system_constraint_factory
.AddMandatory(kMediaStreamSource
,
239 audio_processor
= new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
240 system_constraint_factory
.CreateWebMediaConstraints(), 0,
241 webrtc_audio_device
.get());
242 EXPECT_FALSE(audio_processor
->has_audio_processing());
244 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
245 // |audio_processor|.
246 audio_processor
= NULL
;
249 TEST_F(MediaStreamAudioProcessorTest
, TurnOffDefaultConstraints
) {
250 // Turn off the default constraints and pass it to MediaStreamAudioProcessor.
251 MockMediaConstraintFactory constraint_factory
;
252 constraint_factory
.DisableDefaultAudioConstraints();
253 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
254 new WebRtcAudioDeviceImpl());
255 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
256 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
257 constraint_factory
.CreateWebMediaConstraints(), 0,
258 webrtc_audio_device
.get()));
259 EXPECT_FALSE(audio_processor
->has_audio_processing());
260 audio_processor
->OnCaptureFormatChanged(params_
);
262 ProcessDataAndVerifyFormat(audio_processor
.get(),
263 params_
.sample_rate(),
265 params_
.sample_rate() / 100);
266 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
267 // |audio_processor|.
268 audio_processor
= NULL
;
271 TEST_F(MediaStreamAudioProcessorTest
, VerifyConstraints
) {
272 static const char* kDefaultAudioConstraints
[] = {
273 MediaAudioConstraints::kEchoCancellation
,
274 MediaAudioConstraints::kGoogAudioMirroring
,
275 MediaAudioConstraints::kGoogAutoGainControl
,
276 MediaAudioConstraints::kGoogEchoCancellation
,
277 MediaAudioConstraints::kGoogExperimentalEchoCancellation
,
278 MediaAudioConstraints::kGoogExperimentalAutoGainControl
,
279 MediaAudioConstraints::kGoogExperimentalNoiseSuppression
,
280 MediaAudioConstraints::kGoogHighpassFilter
,
281 MediaAudioConstraints::kGoogNoiseSuppression
,
282 MediaAudioConstraints::kGoogTypingNoiseDetection
,
283 kMediaStreamAudioHotword
286 // Verify mandatory constraints.
287 for (size_t i
= 0; i
< arraysize(kDefaultAudioConstraints
); ++i
) {
288 MockMediaConstraintFactory constraint_factory
;
289 constraint_factory
.AddMandatory(kDefaultAudioConstraints
[i
], false);
290 blink::WebMediaConstraints constraints
=
291 constraint_factory
.CreateWebMediaConstraints();
292 MediaAudioConstraints
audio_constraints(constraints
, 0);
293 EXPECT_FALSE(audio_constraints
.GetProperty(kDefaultAudioConstraints
[i
]));
296 // Verify optional constraints.
297 for (size_t i
= 0; i
< arraysize(kDefaultAudioConstraints
); ++i
) {
298 MockMediaConstraintFactory constraint_factory
;
299 constraint_factory
.AddOptional(kDefaultAudioConstraints
[i
], false);
300 blink::WebMediaConstraints constraints
=
301 constraint_factory
.CreateWebMediaConstraints();
302 MediaAudioConstraints
audio_constraints(constraints
, 0);
303 EXPECT_FALSE(audio_constraints
.GetProperty(kDefaultAudioConstraints
[i
]));
307 // Verify echo cancellation is off when platform aec effect is on.
308 MockMediaConstraintFactory constraint_factory
;
309 MediaAudioConstraints
audio_constraints(
310 constraint_factory
.CreateWebMediaConstraints(),
311 media::AudioParameters::ECHO_CANCELLER
);
312 EXPECT_FALSE(audio_constraints
.GetEchoCancellationProperty());
316 // Verify |kEchoCancellation| overwrite |kGoogEchoCancellation|.
317 MockMediaConstraintFactory constraint_factory_1
;
318 constraint_factory_1
.AddOptional(MediaAudioConstraints::kEchoCancellation
,
320 constraint_factory_1
.AddOptional(
321 MediaAudioConstraints::kGoogEchoCancellation
, false);
322 blink::WebMediaConstraints constraints_1
=
323 constraint_factory_1
.CreateWebMediaConstraints();
324 MediaAudioConstraints
audio_constraints_1(constraints_1
, 0);
325 EXPECT_TRUE(audio_constraints_1
.GetEchoCancellationProperty());
327 MockMediaConstraintFactory constraint_factory_2
;
328 constraint_factory_2
.AddOptional(MediaAudioConstraints::kEchoCancellation
,
330 constraint_factory_2
.AddOptional(
331 MediaAudioConstraints::kGoogEchoCancellation
, true);
332 blink::WebMediaConstraints constraints_2
=
333 constraint_factory_2
.CreateWebMediaConstraints();
334 MediaAudioConstraints
audio_constraints_2(constraints_2
, 0);
335 EXPECT_FALSE(audio_constraints_2
.GetEchoCancellationProperty());
339 // When |kEchoCancellation| is explicitly set to false, the default values
340 // for all the constraints are false.
341 MockMediaConstraintFactory constraint_factory
;
342 constraint_factory
.AddOptional(MediaAudioConstraints::kEchoCancellation
,
344 blink::WebMediaConstraints constraints
=
345 constraint_factory
.CreateWebMediaConstraints();
346 MediaAudioConstraints
audio_constraints(constraints
, 0);
347 for (size_t i
= 0; i
< arraysize(kDefaultAudioConstraints
); ++i
) {
348 EXPECT_FALSE(audio_constraints
.GetProperty(kDefaultAudioConstraints
[i
]));
353 // |kMediaStreamAudioHotword| is always off by default.
354 MockMediaConstraintFactory constraint_factory
;
355 MediaAudioConstraints
audio_constraints(
356 constraint_factory
.CreateWebMediaConstraints(), 0);
357 EXPECT_FALSE(audio_constraints
.GetProperty(kMediaStreamAudioHotword
));
361 TEST_F(MediaStreamAudioProcessorTest
, ValidateConstraints
) {
362 MockMediaConstraintFactory constraint_factory
;
363 const std::string dummy_constraint
= "dummy";
364 constraint_factory
.AddMandatory(dummy_constraint
, true);
365 MediaAudioConstraints
audio_constraints(
366 constraint_factory
.CreateWebMediaConstraints(), 0);
367 EXPECT_FALSE(audio_constraints
.IsValid());
370 // Test crashing with ASAN on Android. crbug.com/468762
371 #if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
372 #define MAYBE_TestAllSampleRates DISABLED_TestAllSampleRates
374 #define MAYBE_TestAllSampleRates TestAllSampleRates
376 TEST_F(MediaStreamAudioProcessorTest
, MAYBE_TestAllSampleRates
) {
377 MockMediaConstraintFactory constraint_factory
;
378 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
379 new WebRtcAudioDeviceImpl());
380 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
381 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
382 constraint_factory
.CreateWebMediaConstraints(), 0,
383 webrtc_audio_device
.get()));
384 EXPECT_TRUE(audio_processor
->has_audio_processing());
386 static const int kSupportedSampleRates
[] =
387 { 8000, 16000, 22050, 32000, 44100, 48000, 88200, 96000 };
388 for (size_t i
= 0; i
< arraysize(kSupportedSampleRates
); ++i
) {
389 int buffer_size
= (kSupportedSampleRates
[i
] / 100) < 128 ?
390 kSupportedSampleRates
[i
] / 100 : 128;
391 media::AudioParameters
params(
392 media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
393 media::CHANNEL_LAYOUT_STEREO
, kSupportedSampleRates
[i
], 16,
395 audio_processor
->OnCaptureFormatChanged(params
);
396 VerifyDefaultComponents(audio_processor
.get());
398 ProcessDataAndVerifyFormat(audio_processor
.get(),
399 kAudioProcessingSampleRate
,
400 kAudioProcessingNumberOfChannel
,
401 kAudioProcessingSampleRate
/ 100);
404 // Set |audio_processor| to NULL to make sure |webrtc_audio_device|
405 // outlives |audio_processor|.
406 audio_processor
= NULL
;
409 // Test that if we have an AEC dump message filter created, we are getting it
410 // correctly in MSAP. Any IPC messages will be deleted since no sender in the
411 // filter will be created.
412 TEST_F(MediaStreamAudioProcessorTest
, GetAecDumpMessageFilter
) {
413 base::MessageLoopForUI message_loop
;
414 scoped_refptr
<AecDumpMessageFilter
> aec_dump_message_filter_(
415 new AecDumpMessageFilter(message_loop
.task_runner(),
416 message_loop
.task_runner()));
418 MockMediaConstraintFactory constraint_factory
;
419 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
420 new WebRtcAudioDeviceImpl());
421 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
422 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
423 constraint_factory
.CreateWebMediaConstraints(), 0,
424 webrtc_audio_device
.get()));
426 EXPECT_TRUE(audio_processor
->aec_dump_message_filter_
.get());
428 audio_processor
= NULL
;
431 TEST_F(MediaStreamAudioProcessorTest
, TestStereoAudio
) {
432 // Set up the correct constraints to turn off the audio processing and turn
433 // on the stereo channels mirroring.
434 MockMediaConstraintFactory constraint_factory
;
435 constraint_factory
.AddMandatory(MediaAudioConstraints::kEchoCancellation
,
437 constraint_factory
.AddMandatory(MediaAudioConstraints::kGoogAudioMirroring
,
439 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
440 new WebRtcAudioDeviceImpl());
441 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
442 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
443 constraint_factory
.CreateWebMediaConstraints(), 0,
444 webrtc_audio_device
.get()));
445 EXPECT_FALSE(audio_processor
->has_audio_processing());
446 const media::AudioParameters
source_params(
447 media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
448 media::CHANNEL_LAYOUT_STEREO
, 48000, 16, 480);
449 audio_processor
->OnCaptureFormatChanged(source_params
);
450 EXPECT_EQ(audio_processor
->OutputFormat().channels(), 2);
452 // Construct left and right channels, and assign different values to the
453 // first data of the left channel and right channel.
454 const int size
= media::AudioBus::CalculateMemorySize(source_params
);
455 scoped_ptr
<float, base::AlignedFreeDeleter
> left_channel(
456 static_cast<float*>(base::AlignedAlloc(size
, 32)));
457 scoped_ptr
<float, base::AlignedFreeDeleter
> right_channel(
458 static_cast<float*>(base::AlignedAlloc(size
, 32)));
459 scoped_ptr
<media::AudioBus
> wrapper
= media::AudioBus::CreateWrapper(
460 source_params
.channels());
461 wrapper
->set_frames(source_params
.frames_per_buffer());
462 wrapper
->SetChannelData(0, left_channel
.get());
463 wrapper
->SetChannelData(1, right_channel
.get());
465 float* left_channel_ptr
= left_channel
.get();
466 left_channel_ptr
[0] = 1.0f
;
468 // Run the test consecutively to make sure the stereo channels are not
469 // flipped back and forth.
470 static const int kNumberOfPacketsForTest
= 100;
471 const base::TimeDelta pushed_capture_delay
=
472 base::TimeDelta::FromMilliseconds(42);
473 for (int i
= 0; i
< kNumberOfPacketsForTest
; ++i
) {
474 audio_processor
->PushCaptureData(*wrapper
, pushed_capture_delay
);
476 media::AudioBus
* processed_data
= nullptr;
477 base::TimeDelta capture_delay
;
479 EXPECT_TRUE(audio_processor
->ProcessAndConsumeData(
480 0, false, &processed_data
, &capture_delay
, &new_volume
));
481 EXPECT_TRUE(processed_data
);
482 EXPECT_EQ(processed_data
->channel(0)[0], 0);
483 EXPECT_NE(processed_data
->channel(1)[0], 0);
484 EXPECT_EQ(pushed_capture_delay
, capture_delay
);
487 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
488 // |audio_processor|.
489 audio_processor
= NULL
;
492 // Disabled on android clang builds due to crbug.com/470499
493 #if defined(__clang__) && defined(OS_ANDROID)
494 #define MAYBE_TestWithKeyboardMicChannel DISABLED_TestWithKeyboardMicChannel
496 #define MAYBE_TestWithKeyboardMicChannel TestWithKeyboardMicChannel
499 TEST_F(MediaStreamAudioProcessorTest
, MAYBE_TestWithKeyboardMicChannel
) {
500 MockMediaConstraintFactory constraint_factory
;
501 constraint_factory
.AddMandatory(
502 MediaAudioConstraints::kGoogExperimentalNoiseSuppression
, true);
503 scoped_refptr
<WebRtcAudioDeviceImpl
> webrtc_audio_device(
504 new WebRtcAudioDeviceImpl());
505 scoped_refptr
<MediaStreamAudioProcessor
> audio_processor(
506 new rtc::RefCountedObject
<MediaStreamAudioProcessor
>(
507 constraint_factory
.CreateWebMediaConstraints(), 0,
508 webrtc_audio_device
.get()));
509 EXPECT_TRUE(audio_processor
->has_audio_processing());
511 media::AudioParameters
params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
512 media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
,
514 audio_processor
->OnCaptureFormatChanged(params
);
516 ProcessDataAndVerifyFormat(audio_processor
.get(),
517 kAudioProcessingSampleRate
,
518 kAudioProcessingNumberOfChannel
,
519 kAudioProcessingSampleRate
/ 100);
520 // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
521 // |audio_processor|.
522 audio_processor
= NULL
;
525 using Point
= webrtc::Point
;
526 using PointVector
= std::vector
<Point
>;
528 void ExpectPointVectorEqual(const PointVector
& expected
,
529 const PointVector
& actual
) {
530 EXPECT_EQ(expected
.size(), actual
.size());
531 for (size_t i
= 0; i
< actual
.size(); ++i
) {
532 EXPECT_EQ(expected
[i
].x(), actual
[i
].x());
533 EXPECT_EQ(expected
[i
].y(), actual
[i
].y());
534 EXPECT_EQ(expected
[i
].z(), actual
[i
].z());
538 TEST(MediaStreamAudioProcessorOptionsTest
, ParseArrayGeometry
) {
539 const PointVector expected_empty
;
540 ExpectPointVectorEqual(expected_empty
, ParseArrayGeometry(""));
541 ExpectPointVectorEqual(expected_empty
, ParseArrayGeometry("0 0 a"));
542 ExpectPointVectorEqual(expected_empty
, ParseArrayGeometry("1 2"));
543 ExpectPointVectorEqual(expected_empty
, ParseArrayGeometry("1 2 3 4"));
546 PointVector
expected(1, Point(-0.02f
, 0, 0));
547 expected
.push_back(Point(0.02f
, 0, 0));
548 ExpectPointVectorEqual(expected
, ParseArrayGeometry("-0.02 0 0 0.02 0 0"));
551 PointVector
expected(1, Point(1, 2, 3));
552 ExpectPointVectorEqual(expected
, ParseArrayGeometry("1 2 3"));
556 } // namespace content