Removed the dependency in GainControlImpl on the ProcessingComponent class

BUG=webrtc:5353

Review URL: https://codereview.webrtc.org/1768943002

Cr-Commit-Position: refs/heads/master@{#11949}
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc
index 119eee9..37a824b 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -80,11 +80,11 @@
 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero");
 
 struct AudioProcessingImpl::ApmPublicSubmodules {
-  ApmPublicSubmodules() : gain_control(nullptr) {}
+  ApmPublicSubmodules() {}
   // Accessed externally of APM without any lock acquired.
   std::unique_ptr<EchoCancellationImpl> echo_cancellation;
   std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
-  GainControlImpl* gain_control;
+  std::unique_ptr<GainControlImpl> gain_control;
   std::unique_ptr<HighPassFilterImpl> high_pass_filter;
   std::unique_ptr<LevelEstimatorImpl> level_estimator;
   std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
@@ -173,8 +173,8 @@
         new EchoCancellationImpl(this, &crit_render_, &crit_capture_));
     public_submodules_->echo_control_mobile.reset(
         new EchoControlMobileImpl(this, &crit_render_, &crit_capture_));
-    public_submodules_->gain_control =
-        new GainControlImpl(this, &crit_capture_, &crit_capture_);
+    public_submodules_->gain_control.reset(
+        new GainControlImpl(this, &crit_capture_, &crit_capture_));
     public_submodules_->high_pass_filter.reset(
         new HighPassFilterImpl(&crit_capture_));
     public_submodules_->level_estimator.reset(
@@ -184,10 +184,8 @@
     public_submodules_->voice_detection.reset(
         new VoiceDetectionImpl(&crit_capture_));
     public_submodules_->gain_control_for_experimental_agc.reset(
-        new GainControlForExperimentalAgc(public_submodules_->gain_control,
-                                          &crit_capture_));
-    private_submodules_->component_list.push_back(
-        public_submodules_->gain_control);
+        new GainControlForExperimentalAgc(
+            public_submodules_->gain_control.get(), &crit_capture_));
   }
 
   SetExtraOptions(config);
@@ -318,6 +316,7 @@
     }
   }
 
+  InitializeGainController();
   InitializeEchoCanceller();
   InitializeEchoControlMobile();
   InitializeExperimentalAgc();
@@ -1093,7 +1092,7 @@
   if (constants_.use_experimental_agc) {
     return public_submodules_->gain_control_for_experimental_agc.get();
   }
-  return public_submodules_->gain_control;
+  return public_submodules_->gain_control.get();
 }
 
 HighPassFilter* AudioProcessingImpl::high_pass_filter() const {
@@ -1127,7 +1126,8 @@
       public_submodules_->high_pass_filter->is_enabled() ||
       public_submodules_->noise_suppression->is_enabled() ||
       public_submodules_->echo_cancellation->is_enabled() ||
-      public_submodules_->echo_control_mobile->is_enabled()) {
+      public_submodules_->echo_control_mobile->is_enabled() ||
+      public_submodules_->gain_control->is_enabled()) {
     return true;
   }
 
@@ -1191,7 +1191,7 @@
   if (constants_.use_experimental_agc) {
     if (!private_submodules_->agc_manager.get()) {
       private_submodules_->agc_manager.reset(new AgcManagerDirect(
-          public_submodules_->gain_control,
+          public_submodules_->gain_control.get(),
           public_submodules_->gain_control_for_experimental_agc.get(),
           constants_.agc_startup_min_volume));
     }
@@ -1247,6 +1247,10 @@
   public_submodules_->echo_cancellation->Initialize();
 }
 
+void AudioProcessingImpl::InitializeGainController() {
+  public_submodules_->gain_control->Initialize();
+}
+
 void AudioProcessingImpl::InitializeEchoControlMobile() {
   public_submodules_->echo_control_mobile->Initialize();
 }
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.h b/webrtc/modules/audio_processing/audio_processing_impl.h
index d79d34c..20ca3a4 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.h
+++ b/webrtc/modules/audio_processing/audio_processing_impl.h
@@ -198,6 +198,8 @@
       EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
   void InitializeEchoCanceller()
       EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
+  void InitializeGainController()
+      EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
   void InitializeEchoControlMobile()
       EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
   int InitializeLocked(const ProcessingConfig& config)
diff --git a/webrtc/modules/audio_processing/gain_control_impl.cc b/webrtc/modules/audio_processing/gain_control_impl.cc
index 04a6c7b..936a286 100644
--- a/webrtc/modules/audio_processing/gain_control_impl.cc
+++ b/webrtc/modules/audio_processing/gain_control_impl.cc
@@ -10,8 +10,7 @@
 
 #include "webrtc/modules/audio_processing/gain_control_impl.h"
 
-#include <assert.h>
-
+#include "webrtc/base/optional.h"
 #include "webrtc/modules/audio_processing/audio_buffer.h"
 #include "webrtc/modules/audio_processing/agc/legacy/gain_control.h"
 
@@ -29,7 +28,7 @@
     case GainControl::kFixedDigital:
       return kAgcModeFixedDigital;
   }
-  assert(false);
+  RTC_DCHECK(false);
   return -1;
 }
 
@@ -42,11 +41,59 @@
 
 }  // namespace
 
+class GainControlImpl::GainController {
+ public:
+  explicit GainController() {
+    state_ = WebRtcAgc_Create();
+    RTC_CHECK(state_);
+  }
+
+  ~GainController() {
+    RTC_DCHECK(state_);
+    WebRtcAgc_Free(state_);
+  }
+
+  Handle* state() {
+    RTC_DCHECK(state_);
+    return state_;
+  }
+
+  void Initialize(int minimum_capture_level,
+                  int maximum_capture_level,
+                  Mode mode,
+                  int sample_rate_hz,
+                  int capture_level) {
+    RTC_DCHECK(state_);
+    int error =
+        WebRtcAgc_Init(state_, minimum_capture_level, maximum_capture_level,
+                       MapSetting(mode), sample_rate_hz);
+    RTC_DCHECK_EQ(0, error);
+
+    set_capture_level(capture_level);
+  }
+
+  void set_capture_level(int capture_level) {
+    capture_level_ = rtc::Optional<int>(capture_level);
+  }
+
+  int get_capture_level() {
+    RTC_DCHECK(capture_level_);
+    return *capture_level_;
+  }
+
+ private:
+  Handle* state_;
+  // TODO(peah): Remove the optional once the initialization is moved into the
+  // ctor.
+  rtc::Optional<int> capture_level_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(GainController);
+};
+
 GainControlImpl::GainControlImpl(const AudioProcessing* apm,
                                  rtc::CriticalSection* crit_render,
                                  rtc::CriticalSection* crit_capture)
-    : ProcessingComponent(),
-      apm_(apm),
+    : apm_(apm),
       crit_render_(crit_render),
       crit_capture_(crit_capture),
       mode_(kAdaptiveAnalog),
@@ -68,20 +115,20 @@
 
 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) {
   rtc::CritScope cs(crit_render_);
-  if (!is_component_enabled()) {
+  if (!enabled_) {
     return AudioProcessing::kNoError;
   }
 
-  assert(audio->num_frames_per_band() <= 160);
+  RTC_DCHECK_GE(160u, audio->num_frames_per_band());
 
   render_queue_buffer_.resize(0);
-  for (size_t i = 0; i < num_handles(); i++) {
-    Handle* my_handle = static_cast<Handle*>(handle(i));
-    int err =
-        WebRtcAgc_GetAddFarendError(my_handle, audio->num_frames_per_band());
+  for (auto& gain_controller : gain_controllers_) {
+    int err = WebRtcAgc_GetAddFarendError(gain_controller->state(),
+                                          audio->num_frames_per_band());
 
-    if (err != AudioProcessing::kNoError)
-      return GetHandleError(my_handle);
+    if (err != AudioProcessing::kNoError) {
+      return AudioProcessing::kUnspecifiedError;
+    }
 
     // Buffer the samples in the render queue.
     render_queue_buffer_.insert(
@@ -106,17 +153,17 @@
 void GainControlImpl::ReadQueuedRenderData() {
   rtc::CritScope cs(crit_capture_);
 
-  if (!is_component_enabled()) {
+  if (!enabled_) {
     return;
   }
 
   while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
     size_t buffer_index = 0;
     const size_t num_frames_per_band =
-        capture_queue_buffer_.size() / num_handles();
-    for (size_t i = 0; i < num_handles(); i++) {
-      Handle* my_handle = static_cast<Handle*>(handle(i));
-      WebRtcAgc_AddFarend(my_handle, &capture_queue_buffer_[buffer_index],
+        capture_queue_buffer_.size() / num_handles_required();
+    for (auto& gain_controller : gain_controllers_) {
+      WebRtcAgc_AddFarend(gain_controller->state(),
+                          &capture_queue_buffer_[buffer_index],
                           num_frames_per_band);
 
       buffer_index += num_frames_per_band;
@@ -127,49 +174,42 @@
 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) {
   rtc::CritScope cs(crit_capture_);
 
-  if (!is_component_enabled()) {
+  if (!enabled_) {
     return AudioProcessing::kNoError;
   }
 
-  assert(audio->num_frames_per_band() <= 160);
-  assert(audio->num_channels() == num_handles());
-
-  int err = AudioProcessing::kNoError;
+  RTC_DCHECK_GE(160u, audio->num_frames_per_band());
+  RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
+  RTC_DCHECK_LE(num_handles_required(), gain_controllers_.size());
 
   if (mode_ == kAdaptiveAnalog) {
-    capture_levels_.assign(num_handles(), analog_capture_level_);
-    for (size_t i = 0; i < num_handles(); i++) {
-      Handle* my_handle = static_cast<Handle*>(handle(i));
-      err = WebRtcAgc_AddMic(
-          my_handle,
-          audio->split_bands(i),
-          audio->num_bands(),
-          audio->num_frames_per_band());
+    int capture_channel = 0;
+    for (auto& gain_controller : gain_controllers_) {
+      gain_controller->set_capture_level(analog_capture_level_);
+      int err = WebRtcAgc_AddMic(
+          gain_controller->state(), audio->split_bands(capture_channel),
+          audio->num_bands(), audio->num_frames_per_band());
 
       if (err != AudioProcessing::kNoError) {
-        return GetHandleError(my_handle);
+        return AudioProcessing::kUnspecifiedError;
       }
+      ++capture_channel;
     }
   } else if (mode_ == kAdaptiveDigital) {
-
-    for (size_t i = 0; i < num_handles(); i++) {
-      Handle* my_handle = static_cast<Handle*>(handle(i));
+    int capture_channel = 0;
+    for (auto& gain_controller : gain_controllers_) {
       int32_t capture_level_out = 0;
+      int err = WebRtcAgc_VirtualMic(
+          gain_controller->state(), audio->split_bands(capture_channel),
+          audio->num_bands(), audio->num_frames_per_band(),
+          analog_capture_level_, &capture_level_out);
 
-      err = WebRtcAgc_VirtualMic(
-          my_handle,
-          audio->split_bands(i),
-          audio->num_bands(),
-          audio->num_frames_per_band(),
-          analog_capture_level_,
-          &capture_level_out);
-
-      capture_levels_[i] = capture_level_out;
+      gain_controller->set_capture_level(capture_level_out);
 
       if (err != AudioProcessing::kNoError) {
-        return GetHandleError(my_handle);
+        return AudioProcessing::kUnspecifiedError;
       }
-
+      ++capture_channel;
     }
   }
 
@@ -179,7 +219,7 @@
 int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) {
   rtc::CritScope cs(crit_capture_);
 
-  if (!is_component_enabled()) {
+  if (!enabled_) {
     return AudioProcessing::kNoError;
   }
 
@@ -187,46 +227,44 @@
     return AudioProcessing::kStreamParameterNotSetError;
   }
 
-  assert(audio->num_frames_per_band() <= 160);
-  assert(audio->num_channels() == num_handles());
+  RTC_DCHECK_GE(160u, audio->num_frames_per_band());
+  RTC_DCHECK_EQ(audio->num_channels(), num_handles_required());
 
   stream_is_saturated_ = false;
-  for (size_t i = 0; i < num_handles(); i++) {
-    Handle* my_handle = static_cast<Handle*>(handle(i));
+  int capture_channel = 0;
+  for (auto& gain_controller : gain_controllers_) {
     int32_t capture_level_out = 0;
     uint8_t saturation_warning = 0;
 
     // The call to stream_has_echo() is ok from a deadlock perspective
     // as the capture lock is allready held.
     int err = WebRtcAgc_Process(
-        my_handle,
-        audio->split_bands_const(i),
-        audio->num_bands(),
-        audio->num_frames_per_band(),
-        audio->split_bands(i),
-        capture_levels_[i],
-        &capture_level_out,
-        apm_->echo_cancellation()->stream_has_echo(),
-        &saturation_warning);
+        gain_controller->state(), audio->split_bands_const(capture_channel),
+        audio->num_bands(), audio->num_frames_per_band(),
+        audio->split_bands(capture_channel),
+        gain_controller->get_capture_level(), &capture_level_out,
+        apm_->echo_cancellation()->stream_has_echo(), &saturation_warning);
 
     if (err != AudioProcessing::kNoError) {
-      return GetHandleError(my_handle);
+      return AudioProcessing::kUnspecifiedError;
     }
 
-    capture_levels_[i] = capture_level_out;
+    gain_controller->set_capture_level(capture_level_out);
     if (saturation_warning == 1) {
       stream_is_saturated_ = true;
     }
+
+    ++capture_channel;
   }
 
   if (mode_ == kAdaptiveAnalog) {
     // Take the analog level to be the average across the handles.
     analog_capture_level_ = 0;
-    for (size_t i = 0; i < num_handles(); i++) {
-      analog_capture_level_ += capture_levels_[i];
+    for (auto& gain_controller : gain_controllers_) {
+      analog_capture_level_ += gain_controller->get_capture_level();
     }
 
-    analog_capture_level_ /= num_handles();
+    analog_capture_level_ /= num_handles_required();
   }
 
   was_analog_level_set_ = false;
@@ -257,12 +295,18 @@
 int GainControlImpl::Enable(bool enable) {
   rtc::CritScope cs_render(crit_render_);
   rtc::CritScope cs_capture(crit_capture_);
-  return EnableComponent(enable);
+  if (enable && !enabled_) {
+    enabled_ = enable;  // Must be set before Initialize() is called.
+    Initialize();
+  } else {
+    enabled_ = enable;
+  }
+  return AudioProcessing::kNoError;
 }
 
 bool GainControlImpl::is_enabled() const {
   rtc::CritScope cs(crit_capture_);
-  return is_component_enabled();
+  return enabled_;
 }
 
 int GainControlImpl::set_mode(Mode mode) {
@@ -273,7 +317,8 @@
   }
 
   mode_ = mode;
-  return Initialize();
+  Initialize();
+  return AudioProcessing::kNoError;
 }
 
 GainControl::Mode GainControlImpl::mode() const {
@@ -299,7 +344,8 @@
   minimum_capture_level_ = minimum;
   maximum_capture_level_ = maximum;
 
-  return Initialize();
+  Initialize();
+  return AudioProcessing::kNoError;
 }
 
 int GainControlImpl::analog_level_minimum() const {
@@ -318,12 +364,13 @@
 }
 
 int GainControlImpl::set_target_level_dbfs(int level) {
-  rtc::CritScope cs(crit_capture_);
   if (level > 31 || level < 0) {
     return AudioProcessing::kBadParameterError;
   }
-
-  target_level_dbfs_ = level;
+  {
+    rtc::CritScope cs(crit_capture_);
+    target_level_dbfs_ = level;
+  }
   return Configure();
 }
 
@@ -333,12 +380,13 @@
 }
 
 int GainControlImpl::set_compression_gain_db(int gain) {
-  rtc::CritScope cs(crit_capture_);
   if (gain < 0 || gain > 90) {
     return AudioProcessing::kBadParameterError;
   }
-
-  compression_gain_db_ = gain;
+  {
+    rtc::CritScope cs(crit_capture_);
+    compression_gain_db_ = gain;
+  }
   return Configure();
 }
 
@@ -348,8 +396,10 @@
 }
 
 int GainControlImpl::enable_limiter(bool enable) {
-  rtc::CritScope cs(crit_capture_);
-  limiter_enabled_ = enable;
+  {
+    rtc::CritScope cs(crit_capture_);
+    limiter_enabled_ = enable;
+  }
   return Configure();
 }
 
@@ -358,26 +408,32 @@
   return limiter_enabled_;
 }
 
-int GainControlImpl::Initialize() {
-  int err = ProcessingComponent::Initialize();
-  if (err != AudioProcessing::kNoError || !is_component_enabled()) {
-    return err;
+void GainControlImpl::Initialize() {
+  rtc::CritScope cs_render(crit_render_);
+  rtc::CritScope cs_capture(crit_capture_);
+  if (!enabled_) {
+    return;
   }
 
+  int sample_rate_hz = apm_->proc_sample_rate_hz();
+  gain_controllers_.resize(num_handles_required());
+  for (auto& gain_controller : gain_controllers_) {
+    if (!gain_controller) {
+      gain_controller.reset(new GainController());
+    }
+    gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_,
+                                mode_, sample_rate_hz, analog_capture_level_);
+  }
+
+  Configure();
+
   AllocateRenderQueue();
-
-  rtc::CritScope cs_capture(crit_capture_);
-  const int n = num_handles();
-  RTC_CHECK_GE(n, 0) << "Bad number of handles: " << n;
-
-  capture_levels_.assign(n, analog_capture_level_);
-  return AudioProcessing::kNoError;
 }
 
 void GainControlImpl::AllocateRenderQueue() {
-  const size_t new_render_queue_element_max_size =
-      std::max<size_t>(static_cast<size_t>(1),
-                       kMaxAllowedValuesOfSamplesPerFrame * num_handles());
+  const size_t new_render_queue_element_max_size = std::max<size_t>(
+      static_cast<size_t>(1),
+      kMaxAllowedValuesOfSamplesPerFrame * num_handles_required());
 
   rtc::CritScope cs_render(crit_render_);
   rtc::CritScope cs_capture(crit_capture_);
@@ -398,26 +454,7 @@
   }
 }
 
-void* GainControlImpl::CreateHandle() const {
-  return WebRtcAgc_Create();
-}
-
-void GainControlImpl::DestroyHandle(void* handle) const {
-  WebRtcAgc_Free(static_cast<Handle*>(handle));
-}
-
-int GainControlImpl::InitializeHandle(void* handle) const {
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
-
-  return WebRtcAgc_Init(static_cast<Handle*>(handle),
-                          minimum_capture_level_,
-                          maximum_capture_level_,
-                          MapSetting(mode_),
-                          apm_->proc_sample_rate_hz());
-}
-
-int GainControlImpl::ConfigureHandle(void* handle) const {
+int GainControlImpl::Configure() {
   rtc::CritScope cs_render(crit_render_);
   rtc::CritScope cs_capture(crit_capture_);
   WebRtcAgcConfig config;
@@ -430,18 +467,19 @@
       static_cast<int16_t>(compression_gain_db_);
   config.limiterEnable = limiter_enabled_;
 
-  return WebRtcAgc_set_config(static_cast<Handle*>(handle), config);
+  int error = AudioProcessing::kNoError;
+  for (auto& gain_controller : gain_controllers_) {
+    const int handle_error =
+        WebRtcAgc_set_config(gain_controller->state(), config);
+    if (handle_error != AudioProcessing::kNoError) {
+      error = handle_error;
+    }
+  }
+  return error;
 }
 
 size_t GainControlImpl::num_handles_required() const {
   // Not locked as it only relies on APM public API which is threadsafe.
   return apm_->num_proc_channels();
 }
-
-int GainControlImpl::GetHandleError(void* handle) const {
-  // The AGC has no get_error() function.
-  // (Despite listing errors in its interface...)
-  assert(handle != NULL);
-  return AudioProcessing::kUnspecifiedError;
-}
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_processing/gain_control_impl.h b/webrtc/modules/audio_processing/gain_control_impl.h
index 942a183..54b8ea7 100644
--- a/webrtc/modules/audio_processing/gain_control_impl.h
+++ b/webrtc/modules/audio_processing/gain_control_impl.h
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "webrtc/base/constructormagic.h"
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/thread_annotations.h"
 #include "webrtc/common_audio/swap_queue.h"
@@ -24,20 +25,18 @@
 
 class AudioBuffer;
 
-class GainControlImpl : public GainControl,
-                        public ProcessingComponent {
+class GainControlImpl : public GainControl {
  public:
   GainControlImpl(const AudioProcessing* apm,
                   rtc::CriticalSection* crit_render,
                   rtc::CriticalSection* crit_capture);
-  virtual ~GainControlImpl();
+  ~GainControlImpl() override;
 
   int ProcessRenderAudio(AudioBuffer* audio);
   int AnalyzeCaptureAudio(AudioBuffer* audio);
   int ProcessCaptureAudio(AudioBuffer* audio);
 
-  // ProcessingComponent implementation.
-  int Initialize() override;
+  void Initialize();
 
   // GainControl implementation.
   bool is_enabled() const override;
@@ -49,6 +48,8 @@
   void ReadQueuedRenderData();
 
  private:
+  class GainController;
+
   // GainControl implementation.
   int Enable(bool enable) override;
   int set_stream_analog_level(int level) override;
@@ -63,15 +64,10 @@
   int analog_level_maximum() const override;
   bool stream_is_saturated() const override;
 
-  // ProcessingComponent implementation.
-  void* CreateHandle() const override;
-  int InitializeHandle(void* handle) const override;
-  int ConfigureHandle(void* handle) const override;
-  void DestroyHandle(void* handle) const override;
-  size_t num_handles_required() const override;
-  int GetHandleError(void* handle) const override;
+  size_t num_handles_required() const;
 
   void AllocateRenderQueue();
+  int Configure();
 
   // Not guarded as its public API is thread safe.
   const AudioProcessing* apm_;
@@ -79,13 +75,14 @@
   rtc::CriticalSection* const crit_render_ ACQUIRED_BEFORE(crit_capture_);
   rtc::CriticalSection* const crit_capture_;
 
+  bool enabled_ = false;
+
   Mode mode_ GUARDED_BY(crit_capture_);
   int minimum_capture_level_ GUARDED_BY(crit_capture_);
   int maximum_capture_level_ GUARDED_BY(crit_capture_);
   bool limiter_enabled_ GUARDED_BY(crit_capture_);
   int target_level_dbfs_ GUARDED_BY(crit_capture_);
   int compression_gain_db_ GUARDED_BY(crit_capture_);
-  std::vector<int> capture_levels_ GUARDED_BY(crit_capture_);
   int analog_capture_level_ GUARDED_BY(crit_capture_);
   bool was_analog_level_set_ GUARDED_BY(crit_capture_);
   bool stream_is_saturated_ GUARDED_BY(crit_capture_);
@@ -99,6 +96,10 @@
   std::unique_ptr<
       SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>>
       render_signal_queue_;
+
+  std::vector<std::unique_ptr<GainController>> gain_controllers_;
+
+  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GainControlImpl);
 };
 }  // namespace webrtc