Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / media_stream_audio_processor_options.cc
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 "content/renderer/media/media_stream_audio_processor_options.h"
6
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/path_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/common/media/media_stream_options.h"
12 #include "content/renderer/media/rtc_media_constraints.h"
13 #include "media/audio/audio_parameters.h"
14 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
15 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h"
16 #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
17
18 namespace content {
19
20 namespace {
21
22 // Constant constraint keys which enables default audio constraints on
23 // mediastreams with audio.
24 struct {
25   const char* key;
26   const char* value;
27 } const kDefaultAudioConstraints[] = {
28   { webrtc::MediaConstraintsInterface::kEchoCancellation,
29     webrtc::MediaConstraintsInterface::kValueTrue },
30 #if defined(OS_CHROMEOS) || defined(OS_MACOSX)
31   // Enable the extended filter mode AEC on platforms with known echo issues.
32   { webrtc::MediaConstraintsInterface::kExperimentalEchoCancellation,
33     webrtc::MediaConstraintsInterface::kValueTrue },
34 #endif
35   { webrtc::MediaConstraintsInterface::kAutoGainControl,
36     webrtc::MediaConstraintsInterface::kValueTrue },
37   { webrtc::MediaConstraintsInterface::kExperimentalAutoGainControl,
38     webrtc::MediaConstraintsInterface::kValueTrue },
39   { webrtc::MediaConstraintsInterface::kNoiseSuppression,
40     webrtc::MediaConstraintsInterface::kValueTrue },
41   { webrtc::MediaConstraintsInterface::kHighpassFilter,
42     webrtc::MediaConstraintsInterface::kValueTrue },
43   { webrtc::MediaConstraintsInterface::kTypingNoiseDetection,
44     webrtc::MediaConstraintsInterface::kValueTrue },
45 #if defined(OS_WIN)
46   { content::kMediaStreamAudioDucking,
47     webrtc::MediaConstraintsInterface::kValueTrue },
48 #endif
49 };
50
51 } // namespace
52
53 void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) {
54   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) {
55     bool already_set_value;
56     if (!webrtc::FindConstraint(constraints, kDefaultAudioConstraints[i].key,
57                                 &already_set_value, NULL)) {
58       constraints->AddOptional(kDefaultAudioConstraints[i].key,
59           kDefaultAudioConstraints[i].value, false);
60     } else {
61       DVLOG(1) << "Constraint " << kDefaultAudioConstraints[i].key
62                << " already set to " << already_set_value;
63     }
64   }
65 }
66
67 bool NeedsAudioProcessing(const blink::WebMediaConstraints& constraints,
68                           int effects) {
69   RTCMediaConstraints native_constraints(constraints);
70   ApplyFixedAudioConstraints(&native_constraints);
71   if (effects & media::AudioParameters::ECHO_CANCELLER) {
72     // If platform echo canceller is enabled, disable the software AEC.
73     native_constraints.AddOptional(
74         MediaConstraintsInterface::kEchoCancellation,
75         MediaConstraintsInterface::kValueFalse, true);
76   }
77   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) {
78     bool value = false;
79     if (webrtc::FindConstraint(&native_constraints,
80                                kDefaultAudioConstraints[i].key, &value, NULL) &&
81         value) {
82       return true;
83     }
84   }
85
86   return false;
87 }
88
89 bool GetPropertyFromConstraints(const MediaConstraintsInterface* constraints,
90                                 const std::string& key) {
91   bool value = false;
92   return webrtc::FindConstraint(constraints, key, &value, NULL) && value;
93 }
94
95 void EnableEchoCancellation(AudioProcessing* audio_processing) {
96 #if defined(OS_ANDROID)
97   // Mobile devices are using AECM.
98   int err = audio_processing->echo_control_mobile()->set_routing_mode(
99       webrtc::EchoControlMobile::kSpeakerphone);
100   err |= audio_processing->echo_control_mobile()->Enable(true);
101   CHECK_EQ(err, 0);
102 #else
103   int err = audio_processing->echo_cancellation()->set_suppression_level(
104       webrtc::EchoCancellation::kHighSuppression);
105
106   // Enable the metrics for AEC.
107   err |= audio_processing->echo_cancellation()->enable_metrics(true);
108   err |= audio_processing->echo_cancellation()->enable_delay_logging(true);
109   err |= audio_processing->echo_cancellation()->Enable(true);
110   CHECK_EQ(err, 0);
111 #endif
112 }
113
114 void EnableNoiseSuppression(AudioProcessing* audio_processing) {
115   int err = audio_processing->noise_suppression()->set_level(
116       webrtc::NoiseSuppression::kHigh);
117   err |= audio_processing->noise_suppression()->Enable(true);
118   CHECK_EQ(err, 0);
119 }
120
121 void EnableHighPassFilter(AudioProcessing* audio_processing) {
122   CHECK_EQ(audio_processing->high_pass_filter()->Enable(true), 0);
123 }
124
125 void EnableTypingDetection(AudioProcessing* audio_processing) {
126   int err = audio_processing->voice_detection()->Enable(true);
127   err |= audio_processing->voice_detection()->set_likelihood(
128       webrtc::VoiceDetection::kVeryLowLikelihood);
129   CHECK_EQ(err, 0);
130 }
131
132 void EnableExperimentalEchoCancellation(AudioProcessing* audio_processing) {
133   webrtc::Config config;
134   config.Set<webrtc::DelayCorrection>(new webrtc::DelayCorrection(true));
135   audio_processing->SetExtraOptions(config);
136 }
137
138 void StartAecDump(AudioProcessing* audio_processing) {
139   // TODO(grunell): Figure out a more suitable directory for the audio dump
140   // data.
141   base::FilePath path;
142 #if defined(CHROMEOS)
143   PathService::Get(base::DIR_TEMP, &path);
144 #elif defined(ANDROID)
145   path = base::FilePath(FILE_PATH_LITERAL("sdcard"));
146 #else
147   PathService::Get(base::DIR_EXE, &path);
148 #endif
149   base::FilePath file = path.Append(FILE_PATH_LITERAL("audio.aecdump"));
150
151 #if defined(OS_WIN)
152   const std::string file_name = base::WideToUTF8(file.value());
153 #else
154   const std::string file_name = file.value();
155 #endif
156   if (audio_processing->StartDebugRecording(file_name.c_str()))
157     DLOG(ERROR) << "Fail to start AEC debug recording";
158 }
159
160 void StopAecDump(AudioProcessing* audio_processing) {
161   if (audio_processing->StopDebugRecording())
162     DLOG(ERROR) << "Fail to stop AEC debug recording";
163 }
164
165 void EnableAutomaticGainControl(AudioProcessing* audio_processing) {
166 #if defined(OS_ANDROID) || defined(OS_IOS)
167   const webrtc::GainControl::Mode mode = webrtc::GainControl::kFixedDigital;
168 #else
169   const webrtc::GainControl::Mode mode = webrtc::GainControl::kAdaptiveAnalog;
170 #endif
171   int err = audio_processing->gain_control()->set_mode(mode);
172   err |= audio_processing->gain_control()->Enable(true);
173   CHECK_EQ(err, 0);
174 }
175
176 }  // namespace content