OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "base/command_line.h" |
| 6 #include "base/file_util.h" |
| 7 #include "base/files/file_path.h" |
| 8 #include "base/path_service.h" |
| 9 #include "content/public/common/content_switches.h" |
| 10 #include "content/renderer/media/rtc_media_constraints.h" |
| 11 #include "content/renderer/media/webrtc_audio_processor.h" |
| 12 #include "media/audio/audio_parameters.h" |
| 13 #include "media/base/audio_bus.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" |
| 17 |
| 18 using ::testing::_; |
| 19 using ::testing::AnyNumber; |
| 20 using ::testing::AtLeast; |
| 21 using ::testing::Return; |
| 22 |
| 23 namespace content { |
| 24 |
| 25 namespace { |
| 26 |
| 27 #if defined(ANDROID) |
| 28 const int kAudioProcessingSampleRate = 16000; |
| 29 #else |
| 30 const int kAudioProcessingSampleRate = 32000; |
| 31 #endif |
| 32 const int kAudioProcessingNumberOfChannel = 1; |
| 33 |
| 34 // The number of packers used for testing. |
| 35 const int kNumberOfPacketsForTest = 100; |
| 36 |
| 37 void ReadDataFromSpeechFile(char* data, int length) { |
| 38 base::FilePath file; |
| 39 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &file)); |
| 40 file = file.Append(FILE_PATH_LITERAL("media")) |
| 41 .Append(FILE_PATH_LITERAL("test")) |
| 42 .Append(FILE_PATH_LITERAL("data")) |
| 43 .Append(FILE_PATH_LITERAL("speech_16b_stereo_48kHz.raw")); |
| 44 DCHECK(base::PathExists(file)); |
| 45 int64 data_file_size64 = 0; |
| 46 DCHECK(file_util::GetFileSize(file, &data_file_size64)); |
| 47 EXPECT_EQ(length, file_util::ReadFile(file, data, length)); |
| 48 DCHECK(data_file_size64 > length); |
| 49 } |
| 50 |
| 51 // Constant constraint keys which enables default audio constraints on |
| 52 // mediastreams with audio. |
| 53 struct { |
| 54 const char* key; |
| 55 const char* value; |
| 56 } const kDefaultAudioConstraints[] = { |
| 57 { webrtc::MediaConstraintsInterface::kEchoCancellation, |
| 58 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 59 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) |
| 60 // Enable the extended filter mode AEC on platforms with known echo issues. |
| 61 { webrtc::MediaConstraintsInterface::kExperimentalEchoCancellation, |
| 62 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 63 #endif |
| 64 { webrtc::MediaConstraintsInterface::kAutoGainControl, |
| 65 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 66 { webrtc::MediaConstraintsInterface::kExperimentalAutoGainControl, |
| 67 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 68 { webrtc::MediaConstraintsInterface::kNoiseSuppression, |
| 69 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 70 { webrtc::MediaConstraintsInterface::kHighpassFilter, |
| 71 webrtc::MediaConstraintsInterface::kValueTrue }, |
| 72 }; |
| 73 |
| 74 void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) { |
| 75 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { |
| 76 constraints->AddMandatory(kDefaultAudioConstraints[i].key, |
| 77 kDefaultAudioConstraints[i].value, false); |
| 78 } |
| 79 } |
| 80 |
| 81 } // namespace |
| 82 |
| 83 class WebRtcAudioProcessorTest : public ::testing::Test { |
| 84 public: |
| 85 WebRtcAudioProcessorTest() |
| 86 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 87 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 512) { |
| 88 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 89 switches::kEnableAudioTrackProcessing); |
| 90 } |
| 91 |
| 92 protected: |
| 93 // Helper method to save duplicated code. |
| 94 void ProcessDataAndVerifyFormat(WebRtcAudioProcessor* audio_processor, |
| 95 int expected_output_sample_rate, |
| 96 int expected_output_channels, |
| 97 int expected_output_buffer_size) { |
| 98 // Read the audio data from a file. |
| 99 const int packet_size = |
| 100 params_.frames_per_buffer() * 2 * params_.channels(); |
| 101 const size_t length = packet_size * kNumberOfPacketsForTest; |
| 102 scoped_ptr<char[]> capture_data(new char[length]); |
| 103 ReadDataFromSpeechFile(capture_data.get(), length); |
| 104 const int16* data_ptr = reinterpret_cast<const int16*>(capture_data.get()); |
| 105 scoped_ptr<media::AudioBus> data_bus = media::AudioBus::Create( |
| 106 params_.channels(), params_.frames_per_buffer()); |
| 107 for (int i = 0; i < kNumberOfPacketsForTest; ++i) { |
| 108 data_bus->FromInterleaved(data_ptr, data_bus->frames(), 2); |
| 109 audio_processor->PushCaptureData(data_bus.get()); |
| 110 |
| 111 // Feed data as render data to the processor, this does not cost anything |
| 112 // when the audio processing is off in the processor. |
| 113 audio_processor->PushRenderData( |
| 114 data_ptr, |
| 115 params_.sample_rate(), params_.channels(), |
| 116 params_.frames_per_buffer(), 10); |
| 117 |
| 118 // Process and consume the data in the processor. |
| 119 int16* output = NULL; |
| 120 while(audio_processor->ProcessAndConsumeData(10, 255, false, &output)) { |
| 121 EXPECT_TRUE(output != NULL); |
| 122 EXPECT_EQ(audio_processor->OutputFormat().sample_rate(), |
| 123 expected_output_sample_rate); |
| 124 EXPECT_EQ(audio_processor->OutputFormat().channels(), |
| 125 expected_output_channels); |
| 126 EXPECT_EQ(audio_processor->OutputFormat().frames_per_buffer(), |
| 127 expected_output_buffer_size); |
| 128 } |
| 129 |
| 130 data_ptr += params_.frames_per_buffer() * params_.channels(); |
| 131 } |
| 132 } |
| 133 |
| 134 media::AudioParameters params_; |
| 135 }; |
| 136 |
| 137 TEST_F(WebRtcAudioProcessorTest, WithoutAudioProcessing) { |
| 138 // Setup the audio processor with empty constraint. |
| 139 RTCMediaConstraints constraints; |
| 140 WebRtcAudioProcessor audio_processor(&constraints); |
| 141 audio_processor.SetCaptureFormat(params_); |
| 142 EXPECT_FALSE(audio_processor.has_audio_processing()); |
| 143 |
| 144 ProcessDataAndVerifyFormat(&audio_processor, |
| 145 params_.sample_rate(), |
| 146 params_.channels(), |
| 147 params_.sample_rate() / 100); |
| 148 } |
| 149 |
| 150 TEST_F(WebRtcAudioProcessorTest, WithAudioProcessing) { |
| 151 // Setup the audio processor with default constraint. |
| 152 RTCMediaConstraints constraints; |
| 153 ApplyFixedAudioConstraints(&constraints); |
| 154 WebRtcAudioProcessor audio_processor(&constraints); |
| 155 audio_processor.SetCaptureFormat(params_); |
| 156 EXPECT_TRUE(audio_processor.has_audio_processing()); |
| 157 |
| 158 ProcessDataAndVerifyFormat(&audio_processor, |
| 159 kAudioProcessingSampleRate, |
| 160 kAudioProcessingNumberOfChannel, |
| 161 kAudioProcessingSampleRate / 100); |
| 162 } |
| 163 |
| 164 } // namespace content |
OLD | NEW |