1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/files/file_path.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/aligned_memory.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/path_service.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/common/content_switches.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/media_stream_request.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/renderer/media/media_stream_audio_processor.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/media_stream_audio_processor_options.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/renderer/media/mock_media_constraint_factory.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/audio/audio_parameters.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/base/audio_bus.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using ::testing::_;
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using ::testing::AnyNumber;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using ::testing::AtLeast;
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using ::testing::Return;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(ANDROID)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kAudioProcessingSampleRate = 16000;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kAudioProcessingSampleRate = 32000;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kAudioProcessingNumberOfChannel = 1;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The number of packers used for testing.
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kNumberOfPacketsForTest = 100;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ReadDataFromSpeechFile(char* data, int length) {
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::FilePath file;
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &file));
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file = file.Append(FILE_PATH_LITERAL("media"))
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             .Append(FILE_PATH_LITERAL("test"))
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             .Append(FILE_PATH_LITERAL("data"))
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             .Append(FILE_PATH_LITERAL("speech_16b_stereo_48kHz.raw"));
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(base::PathExists(file));
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 data_file_size64 = 0;
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(base::GetFileSize(file, &data_file_size64));
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(length, base::ReadFile(file, data, length));
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(data_file_size64 > length);
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MediaStreamAudioProcessorTest : public ::testing::Test {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaStreamAudioProcessorTest()
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 512) {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Helper method to save duplicated code.
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void ProcessDataAndVerifyFormat(MediaStreamAudioProcessor* audio_processor,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int expected_output_sample_rate,
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int expected_output_channels,
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int expected_output_buffer_size) {
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Read the audio data from a file.
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const media::AudioParameters& params = audio_processor->InputFormat();
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const int packet_size =
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        params.frames_per_buffer() * 2 * params.channels();
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const size_t length = packet_size * kNumberOfPacketsForTest;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<char[]> capture_data(new char[length]);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ReadDataFromSpeechFile(capture_data.get(), length);
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const int16* data_ptr = reinterpret_cast<const int16*>(capture_data.get());
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<media::AudioBus> data_bus = media::AudioBus::Create(
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        params.channels(), params.frames_per_buffer());
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (int i = 0; i < kNumberOfPacketsForTest; ++i) {
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      data_bus->FromInterleaved(data_ptr, data_bus->frames(), 2);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      audio_processor->PushCaptureData(data_bus.get());
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // |audio_processor| does nothing when the audio processing is off in
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // the processor.
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      webrtc::AudioProcessing* ap = audio_processor->audio_processing_.get();
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const bool is_aec_enabled = ap && ap->echo_control_mobile()->is_enabled();
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // AEC should be turned off for mobiles.
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(!ap || !ap->echo_cancellation()->is_enabled());
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const bool is_aec_enabled = ap && ap->echo_cancellation()->is_enabled();
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (is_aec_enabled) {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        audio_processor->OnPlayoutData(data_bus.get(), params.sample_rate(),
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       10);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int16* output = NULL;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int new_volume = 0;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      while(audio_processor->ProcessAndConsumeData(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(10), 255, false, &new_volume,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          &output)) {
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        EXPECT_TRUE(output != NULL);
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        EXPECT_EQ(audio_processor->OutputFormat().sample_rate(),
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  expected_output_sample_rate);
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        EXPECT_EQ(audio_processor->OutputFormat().channels(),
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  expected_output_channels);
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        EXPECT_EQ(audio_processor->OutputFormat().frames_per_buffer(),
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  expected_output_buffer_size);
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      data_ptr += params.frames_per_buffer() * params.channels();
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void VerifyDefaultComponents(MediaStreamAudioProcessor* audio_processor) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::AudioProcessing* audio_processing =
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        audio_processor->audio_processing_.get();
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->echo_control_mobile()->is_enabled());
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->echo_control_mobile()->routing_mode() ==
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::EchoControlMobile::kSpeakerphone);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(audio_processing->echo_cancellation()->is_enabled());
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif !defined(OS_IOS)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->echo_cancellation()->is_enabled());
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->echo_cancellation()->suppression_level() ==
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::EchoCancellation::kHighSuppression);
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->echo_cancellation()->are_metrics_enabled());
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        audio_processing->echo_cancellation()->is_delay_logging_enabled());
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->noise_suppression()->is_enabled());
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->noise_suppression()->level() ==
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::NoiseSuppression::kHigh);
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->high_pass_filter()->is_enabled());
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->gain_control()->is_enabled());
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->gain_control()->mode() ==
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::GainControl::kFixedDigital);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(audio_processing->voice_detection()->is_enabled());
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->gain_control()->mode() ==
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::GainControl::kAdaptiveAnalog);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->voice_detection()->is_enabled());
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(audio_processing->voice_detection()->likelihood() ==
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        webrtc::VoiceDetection::kVeryLowLikelihood);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  media::AudioParameters params_;
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, WithoutAudioProcessing) {
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Setup the audio processor with disabled flag on.
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CommandLine::ForCurrentProcess()->AppendSwitch(
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      switches::kDisableAudioTrackProcessing);
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaConstraintFactory constraint_factory;
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new WebRtcAudioDeviceImpl());
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          constraint_factory.CreateWebMediaConstraints(), 0,
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          webrtc_audio_device.get()));
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(audio_processor->has_audio_processing());
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor->OnCaptureFormatChanged(params_);
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProcessDataAndVerifyFormat(audio_processor.get(),
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             params_.sample_rate(),
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             params_.channels(),
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             params_.sample_rate() / 100);
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |audio_processor|.
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor = NULL;
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, WithAudioProcessing) {
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaConstraintFactory constraint_factory;
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new WebRtcAudioDeviceImpl());
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          constraint_factory.CreateWebMediaConstraints(), 0,
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          webrtc_audio_device.get()));
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(audio_processor->has_audio_processing());
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor->OnCaptureFormatChanged(params_);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  VerifyDefaultComponents(audio_processor.get());
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProcessDataAndVerifyFormat(audio_processor.get(),
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             kAudioProcessingSampleRate,
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             kAudioProcessingNumberOfChannel,
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             kAudioProcessingSampleRate / 100);
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |audio_processor|.
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor = NULL;
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, VerifyTabCaptureWithoutAudioProcessing) {
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new WebRtcAudioDeviceImpl());
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create MediaStreamAudioProcessor instance for kMediaStreamSourceTab source.
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaConstraintFactory tab_constraint_factory;
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string tab_string = kMediaStreamSourceTab;
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  tab_constraint_factory.AddMandatory(kMediaStreamSource,
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      tab_string);
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          tab_constraint_factory.CreateWebMediaConstraints(), 0,
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          webrtc_audio_device.get()));
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(audio_processor->has_audio_processing());
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor->OnCaptureFormatChanged(params_);
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProcessDataAndVerifyFormat(audio_processor.get(),
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.sample_rate(),
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.channels(),
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.sample_rate() / 100);
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create MediaStreamAudioProcessor instance for kMediaStreamSourceSystem
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // source.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaConstraintFactory system_constraint_factory;
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string system_string = kMediaStreamSourceSystem;
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  system_constraint_factory.AddMandatory(kMediaStreamSource,
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         system_string);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  audio_processor = new rtc::RefCountedObject<MediaStreamAudioProcessor>(
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      system_constraint_factory.CreateWebMediaConstraints(), 0,
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      webrtc_audio_device.get());
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(audio_processor->has_audio_processing());
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |audio_processor|.
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor = NULL;
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Turn off the default constraints and pass it to MediaStreamAudioProcessor.
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MockMediaConstraintFactory constraint_factory;
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  constraint_factory.DisableDefaultAudioConstraints();
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new WebRtcAudioDeviceImpl());
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          constraint_factory.CreateWebMediaConstraints(), 0,
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          webrtc_audio_device.get()));
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(audio_processor->has_audio_processing());
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor->OnCaptureFormatChanged(params_);
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProcessDataAndVerifyFormat(audio_processor.get(),
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.sample_rate(),
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.channels(),
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             params_.sample_rate() / 100);
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |audio_processor|.
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  audio_processor = NULL;
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, VerifyConstraints) {
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static const char* kDefaultAudioConstraints[] = {
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kEchoCancellation,
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogAudioMirroring,
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogAutoGainControl,
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogEchoCancellation,
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogExperimentalEchoCancellation,
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogExperimentalAutoGainControl,
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogExperimentalNoiseSuppression,
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogHighpassFilter,
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogNoiseSuppression,
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints::kGoogTypingNoiseDetection
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Verify mandatory constraints.
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory;
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory.AddMandatory(kDefaultAudioConstraints[i], false);
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    blink::WebMediaConstraints constraints =
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory.CreateWebMediaConstraints();
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints(constraints, 0);
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Verify optional constraints.
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory;
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory.AddOptional(kDefaultAudioConstraints[i], false);
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    blink::WebMediaConstraints constraints =
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory.CreateWebMediaConstraints();
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints(constraints, 0);
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Verify echo cancellation is off when platform aec effect is on.
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory;
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints(
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory.CreateWebMediaConstraints(),
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        media::AudioParameters::ECHO_CANCELLER);
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints.GetEchoCancellationProperty());
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Verify |kEchoCancellation| overwrite |kGoogEchoCancellation|.
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory_1;
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory_1.AddOptional(MediaAudioConstraints::kEchoCancellation,
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   true);
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory_1.AddOptional(
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        MediaAudioConstraints::kGoogEchoCancellation, false);
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    blink::WebMediaConstraints constraints_1 =
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory_1.CreateWebMediaConstraints();
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints_1(constraints_1, 0);
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(audio_constraints_1.GetEchoCancellationProperty());
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory_2;
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory_2.AddOptional(MediaAudioConstraints::kEchoCancellation,
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     false);
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory_2.AddOptional(
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        MediaAudioConstraints::kGoogEchoCancellation, true);
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    blink::WebMediaConstraints constraints_2 =
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory_2.CreateWebMediaConstraints();
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints_2(constraints_2, 0);
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints_2.GetEchoCancellationProperty());
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // When |kEchoCancellation| is explicitly set to false, the default values
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // for all the constraints except |kMediaStreamAudioDucking| are false.
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockMediaConstraintFactory constraint_factory;
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    constraint_factory.AddOptional(MediaAudioConstraints::kEchoCancellation,
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   false);
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    blink::WebMediaConstraints constraints =
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        constraint_factory.CreateWebMediaConstraints();
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MediaAudioConstraints audio_constraints(constraints, 0);
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kDefaultAudioConstraints); ++i) {
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      EXPECT_FALSE(audio_constraints.GetProperty(kDefaultAudioConstraints[i]));
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints.NeedsAudioProcessing());
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(audio_constraints.GetProperty(kMediaStreamAudioDucking));
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(audio_constraints.GetProperty(kMediaStreamAudioDucking));
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, ValidateConstraints) {
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaConstraintFactory constraint_factory;
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string dummy_constraint = "dummy";
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  constraint_factory.AddMandatory(dummy_constraint, true);
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaAudioConstraints audio_constraints(
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      constraint_factory.CreateWebMediaConstraints(), 0);
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(audio_constraints.IsValid());
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(MediaStreamAudioProcessorTest, TestAllSampleRates) {
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockMediaConstraintFactory constraint_factory;
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new WebRtcAudioDeviceImpl());
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          constraint_factory.CreateWebMediaConstraints(), 0,
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          webrtc_audio_device.get()));
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(audio_processor->has_audio_processing());
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  static const int kSupportedSampleRates[] =
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      { 8000, 16000, 22050, 32000, 44100, 48000, 88200, 96000 };
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kSupportedSampleRates); ++i) {
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int buffer_size = (kSupportedSampleRates[i] / 100)  < 128 ?
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        kSupportedSampleRates[i] / 100 : 128;
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    media::AudioParameters params(
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        media::CHANNEL_LAYOUT_STEREO, kSupportedSampleRates[i], 16,
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        buffer_size);
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    audio_processor->OnCaptureFormatChanged(params);
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    VerifyDefaultComponents(audio_processor.get());
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ProcessDataAndVerifyFormat(audio_processor.get(),
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               kAudioProcessingSampleRate,
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               kAudioProcessingNumberOfChannel,
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               kAudioProcessingSampleRate / 100);
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set |audio_processor| to NULL to make sure |webrtc_audio_device|
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // outlives |audio_processor|.
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  audio_processor = NULL;
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Test that if we have an AEC dump message filter created, we are getting it
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// correctly in MSAP. Any IPC messages will be deleted since no sender in the
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// filter will be created.
391116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::MessageLoopForUI message_loop;
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_(
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new AecDumpMessageFilter(message_loop.message_loop_proxy(),
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               message_loop.message_loop_proxy()));
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockMediaConstraintFactory constraint_factory;
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new WebRtcAudioDeviceImpl());
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          constraint_factory.CreateWebMediaConstraints(), 0,
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          webrtc_audio_device.get()));
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get());
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_processor = NULL;
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
410116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Set up the correct constraints to turn off the audio processing and turn
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // on the stereo channels mirroring.
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockMediaConstraintFactory constraint_factory;
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  constraint_factory.AddMandatory(MediaAudioConstraints::kEchoCancellation,
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  false);
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  constraint_factory.AddMandatory(MediaAudioConstraints::kGoogAudioMirroring,
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  true);
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new WebRtcAudioDeviceImpl());
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<MediaStreamAudioProcessor> audio_processor(
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<MediaStreamAudioProcessor>(
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          constraint_factory.CreateWebMediaConstraints(), 0,
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          webrtc_audio_device.get()));
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(audio_processor->has_audio_processing());
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const media::AudioParameters source_params(
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      media::CHANNEL_LAYOUT_STEREO, 48000, 16, 480);
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_processor->OnCaptureFormatChanged(source_params);
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(audio_processor->OutputFormat().channels(), 2);
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Construct left and right channels, and assign different values to the
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // first data of the left channel and right channel.
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int size = media::AudioBus::CalculateMemorySize(source_params);
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<float, base::AlignedFreeDeleter> left_channel(
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      static_cast<float*>(base::AlignedAlloc(size, 32)));
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<float, base::AlignedFreeDeleter> right_channel(
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      static_cast<float*>(base::AlignedAlloc(size, 32)));
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<media::AudioBus> wrapper = media::AudioBus::CreateWrapper(
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      source_params.channels());
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wrapper->set_frames(source_params.frames_per_buffer());
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wrapper->SetChannelData(0, left_channel.get());
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wrapper->SetChannelData(1, right_channel.get());
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  wrapper->Zero();
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  float* left_channel_ptr = left_channel.get();
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  left_channel_ptr[0] = 1.0f;
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // A audio bus used for verifying the output data values.
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<media::AudioBus> output_bus = media::AudioBus::Create(
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      audio_processor->OutputFormat());
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Run the test consecutively to make sure the stereo channels are not
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // flipped back and forth.
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const int kNumberOfPacketsForTest = 100;
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (int i = 0; i < kNumberOfPacketsForTest; ++i) {
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    audio_processor->PushCaptureData(wrapper.get());
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int16* output = NULL;
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int new_volume = 0;
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(audio_processor->ProcessAndConsumeData(
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::TimeDelta::FromMilliseconds(0), 0, false, &new_volume, &output));
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output_bus->FromInterleaved(output, output_bus->frames(), 2);
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(output != NULL);
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_EQ(output_bus->channel(0)[0], 0);
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_NE(output_bus->channel(1)[0], 0);
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |audio_processor|.
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_processor = NULL;
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
473