190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef MEDIA_AUDIO_AGC_AUDIO_STREAM_H_
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define MEDIA_AUDIO_AGC_AUDIO_STREAM_H_
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h"
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/synchronization/lock.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/threading/thread_checker.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/audio/audio_io.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The template based AgcAudioStream implements platform-independent parts
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// of the AudioInterface interface. Supported interfaces to pass as
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// AudioInterface are AudioIntputStream and AudioOutputStream. Each platform-
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// dependent implementation should derive from this class.
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Usage example (on Windows):
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//  class WASAPIAudioInputStream : public AgcAudioStream<AudioInputStream> {
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   public:
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//    WASAPIAudioInputStream();
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//    ...
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//  };
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Call flow example:
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   1) User creates AgcAudioStream<AudioInputStream>
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   2) User calls AudioInputStream::SetAutomaticGainControl(true) =>
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//      AGC usage is now initialized but not yet started.
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   3) User calls AudioInputStream::Start() => implementation calls
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//      AgcAudioStream<AudioInputStream>::StartAgc() which detects that AGC
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//      is enabled and then starts the periodic AGC timer.
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   4) Microphone volume samples are now taken and included in all
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//      AudioInputCallback::OnData() callbacks.
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//   5) User calls AudioInputStream::Stop() => implementation calls
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//      AgcAudioStream<AudioInputStream>::StopAgc() which stops the timer.
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Note that, calling AudioInputStream::SetAutomaticGainControl(false) while
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// AGC measurements are active will not have an effect until StopAgc(),
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// StartAgc() are called again since SetAutomaticGainControl() only sets a
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// a state.
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Calling SetAutomaticGainControl(true) enables the AGC and StartAgc() starts
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// a periodic timer which calls QueryAndStoreNewMicrophoneVolume()
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// approximately once every second. QueryAndStoreNewMicrophoneVolume() asks
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// the actual microphone about its current volume level. This value is
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// normalized and stored so it can be read by GetAgcVolume() when the real-time
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// audio thread needs the value. The main idea behind this scheme is to avoid
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// accessing the audio hardware from the real-time audio thread and to ensure
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// that we don't take new microphone-level samples too often (~1 Hz is a
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// suitable compromise). The timer will be active until StopAgc() is called.
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This class should be created and destroyed on the audio manager thread and
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// a thread checker is added to ensure that this is the case (uses DCHECK).
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// All methods except GetAgcVolume() should be called on the creating thread
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// as well to ensure that thread safety is maintained. It will also guarantee
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// that the periodic timer runs on the audio manager thread.
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// |normalized_volume_|, which is updated by QueryAndStoreNewMicrophoneVolume()
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// and read in GetAgcVolume(), is protected by a lock to ensure that it can
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// be accessed from any real-time audio thread that needs it to update the its
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// AGC volume.
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media {
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)template <typename AudioInterface>
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class MEDIA_EXPORT AgcAudioStream : public AudioInterface {
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Time between two successive timer events.
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static const int kIntervalBetweenVolumeUpdatesMs = 1000;
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AgcAudioStream()
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : agc_is_enabled_(false), max_volume_(0.0), normalized_volume_(0.0) {
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~AgcAudioStream() {
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected:
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Starts the periodic timer which periodically checks and updates the
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // current microphone volume level.
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The timer is only started if AGC mode is first enabled using the
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // SetAutomaticGainControl() method.
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void StartAgc() {
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!agc_is_enabled_ || timer_.IsRunning())
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Query and cache the volume to avoid sending 0 as volume to AGC at the
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // beginning of the audio stream, otherwise AGC will try to raise the
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // volume from 0.
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    QueryAndStoreNewMicrophoneVolume();
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    timer_.Start(FROM_HERE,
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(kIntervalBetweenVolumeUpdatesMs),
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        this, &AgcAudioStream::QueryAndStoreNewMicrophoneVolume);
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Stops the periodic timer which periodically checks and updates the
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // current microphone volume level.
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void StopAgc() {
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (timer_.IsRunning())
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      timer_.Stop();
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Stores a new microphone volume level by checking the audio input device.
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Called on the audio manager thread.
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void UpdateAgcVolume() {
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!timer_.IsRunning())
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return;
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // We take new volume samples once every second when the AGC is enabled.
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // To ensure that a new setting has an immediate effect, the new volume
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // setting is cached here. It will ensure that the next OnData() callback
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // will contain a new valid volume level. If this approach was not taken,
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // we could report invalid volume levels to the client for a time period
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // of up to one second.
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    QueryAndStoreNewMicrophoneVolume();
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Gets the latest stored volume level if AGC is enabled.
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Called at each capture callback on a real-time capture thread (platform
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // dependent).
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void GetAgcVolume(double* normalized_volume) {
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::AutoLock lock(lock_);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *normalized_volume = normalized_volume_;
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Sets the automatic gain control (AGC) to on or off. When AGC is enabled,
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the microphone volume is queried periodically and the volume level can
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // be read in each AudioInputCallback::OnData() callback and fed to the
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // render-side AGC. User must call StartAgc() as well to start measuring
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the microphone level.
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetAutomaticGainControl(bool enabled) OVERRIDE {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DVLOG(1) << "SetAutomaticGainControl(enabled=" << enabled << ")";
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    agc_is_enabled_ = enabled;
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Gets the current automatic gain control state.
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool GetAutomaticGainControl() OVERRIDE {
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return agc_is_enabled_;
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Takes a new microphone volume sample and stores it in |normalized_volume_|.
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Range is normalized to [0.0,1.0] or [0.0, 1.5] on Linux.
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // This method is called periodically when AGC is enabled and always on the
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // audio manager thread. We use it to read the current microphone level and
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // to store it so it can be read by the main capture thread. By using this
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // approach, we can avoid accessing audio hardware from a real-time audio
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // thread and it leads to a more stable capture performance.
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void QueryAndStoreNewMicrophoneVolume() {
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Cach the maximum volume if this is the first time we ask for it.
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (max_volume_ == 0.0)
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      max_volume_ = static_cast<AudioInterface*>(this)->GetMaxVolume();
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Retrieve the current volume level by asking the audio hardware.
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Range is normalized to [0.0,1.0] or [0.0, 1.5] on Linux.
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (max_volume_ != 0.0) {
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      double normalized_volume =
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          static_cast<AudioInterface*>(this)->GetVolume() / max_volume_;
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::AutoLock auto_lock(lock_);
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      normalized_volume_ = normalized_volume;
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Ensures that this class is created and destroyed on the same thread.
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::ThreadChecker thread_checker_;
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Repeating timer which cancels itself when it goes out of scope.
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Used to check the microphone volume periodically.
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::RepeatingTimer<AgcAudioStream<AudioInterface> > timer_;
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // True when automatic gain control is enabled, false otherwise.
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool agc_is_enabled_;
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Stores the maximum volume which is used for normalization to a volume
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // range of [0.0, 1.0].
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  double max_volume_;
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Contains last result of internal call to GetVolume(). We save resources
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // by not querying the capture volume for each callback. Guarded by |lock_|.
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The range is normalized to [0.0, 1.0].
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  double normalized_volume_;
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Protects |normalized_volume_| .
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Lock lock_;
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AgcAudioStream<AudioInterface>);
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace media
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // MEDIA_AUDIO_AGC_AUDIO_STREAM_H_
205