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
;
29 using media::AudioParameters
;
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();
44 const int kAudioProcessingSampleRate
= 16000;
46 const int kAudioProcessingSampleRate
= 48000;
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
) {
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
);
71 class MediaStreamAudioProcessorTest
: public ::testing::Test
{
73 MediaStreamAudioProcessorTest()
74 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
75 media::CHANNEL_LAYOUT_STEREO
, 48000, 16, 512) {
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
) {
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
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());
124 const bool is_aec_enabled
= ap
&& ap
->echo_cancellation()->is_enabled();
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
;
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());
172 audio_processing
->echo_cancellation()->is_delay_logging_enabled());
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());
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
);
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
201 #define MAYBE_WithAudioProcessing WithAudioProcessing
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
,
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(),
242 params_
.sample_rate() / 100);
244 // Create MediaStreamAudioProcessor instance for kMediaStreamSourceSystem
246 MockMediaConstraintFactory system_constraint_factory
;
247 const std::string system_string
= kMediaStreamSourceSystem
;
248 system_constraint_factory
.AddMandatory(kMediaStreamSource
,
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(),
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
,
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
,
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
,
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
446 #define MAYBE_TestAllSampleRates TestAllSampleRates
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,
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
,
509 constraint_factory
.AddMandatory(MediaAudioConstraints::kGoogAudioMirroring
,
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());
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
;
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
568 #define MAYBE_TestWithKeyboardMicChannel TestWithKeyboardMicChannel
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
,
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