Home | History | Annotate | Download | only in audio
      1 // Copyright (c) 2012 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 // Low-latency audio capturing class utilizing audio input stream provided
      6 // by a server (browser) process by use of an IPC interface.
      7 //
      8 // Relationship of classes:
      9 //
     10 //  AudioInputController                 AudioInputDevice
     11 //           ^                                  ^
     12 //           |                                  |
     13 //           v                  IPC             v
     14 // AudioInputRendererHost  <----------->  AudioInputIPC
     15 //           ^                            (AudioInputMessageFilter)
     16 //           |
     17 //           v
     18 // AudioInputDeviceManager
     19 //
     20 // Transportation of audio samples from the browser to the render process
     21 // is done by using shared memory in combination with a SyncSocket.
     22 // The AudioInputDevice user registers an AudioInputDevice::CaptureCallback by
     23 // calling Initialize().  The callback will be called with recorded audio from
     24 // the underlying audio layers.
     25 // The session ID is used by the AudioInputRendererHost to start the device
     26 // referenced by this ID.
     27 //
     28 // State sequences:
     29 //
     30 // Start -> InitializeOnIOThread -> CreateStream ->
     31 //       <- OnStreamCreated <-
     32 //       -> StartOnIOThread -> PlayStream ->
     33 //
     34 //
     35 // AudioInputDevice::Capture => low latency audio transport on audio thread =>
     36 //                               |
     37 // Stop --> ShutDownOnIOThread ------>  CloseStream -> Close
     38 //
     39 // This class depends on two threads to function:
     40 //
     41 // 1. An IO thread.
     42 //    This thread is used to asynchronously process Start/Stop etc operations
     43 //    that are available via the public interface.  The public methods are
     44 //    asynchronous and simply post a task to the IO thread to actually perform
     45 //    the work.
     46 // 2. Audio transport thread.
     47 //    Responsible for calling the CaptureCallback and feed audio samples from
     48 //    the server side audio layer using a socket and shared memory.
     49 //
     50 // Implementation notes:
     51 // - The user must call Stop() before deleting the class instance.
     52 
     53 #ifndef MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
     54 #define MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
     55 
     56 #include <string>
     57 
     58 #include "base/basictypes.h"
     59 #include "base/compiler_specific.h"
     60 #include "base/memory/scoped_ptr.h"
     61 #include "base/memory/shared_memory.h"
     62 #include "media/audio/audio_device_thread.h"
     63 #include "media/audio/audio_input_ipc.h"
     64 #include "media/audio/audio_parameters.h"
     65 #include "media/audio/scoped_task_runner_observer.h"
     66 #include "media/base/audio_capturer_source.h"
     67 #include "media/base/media_export.h"
     68 
     69 namespace media {
     70 
     71 // TODO(henrika): This class is based on the AudioOutputDevice class and it has
     72 // many components in common. Investigate potential for re-factoring.
     73 // See http://crbug.com/179597.
     74 // TODO(henrika): Add support for event handling (e.g. OnStateChanged,
     75 // OnCaptureStopped etc.) and ensure that we can deliver these notifications
     76 // to any clients using this class.
     77 class MEDIA_EXPORT AudioInputDevice
     78     : NON_EXPORTED_BASE(public AudioCapturerSource),
     79       NON_EXPORTED_BASE(public AudioInputIPCDelegate),
     80       NON_EXPORTED_BASE(public ScopedTaskRunnerObserver) {
     81  public:
     82   // NOTE: Clients must call Initialize() before using.
     83   AudioInputDevice(
     84       scoped_ptr<AudioInputIPC> ipc,
     85       const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
     86 
     87   // AudioCapturerSource implementation.
     88   virtual void Initialize(const AudioParameters& params,
     89                           CaptureCallback* callback,
     90                           int session_id) OVERRIDE;
     91   virtual void Start() OVERRIDE;
     92   virtual void Stop() OVERRIDE;
     93   virtual void SetVolume(double volume) OVERRIDE;
     94   virtual void SetAutomaticGainControl(bool enabled) OVERRIDE;
     95 
     96  protected:
     97   friend class base::RefCountedThreadSafe<AudioInputDevice>;
     98   virtual ~AudioInputDevice();
     99 
    100   // Methods called on IO thread ----------------------------------------------
    101   // AudioInputIPCDelegate implementation.
    102   virtual void OnStreamCreated(base::SharedMemoryHandle handle,
    103                                base::SyncSocket::Handle socket_handle,
    104                                int length,
    105                                int total_segments) OVERRIDE;
    106   virtual void OnVolume(double volume) OVERRIDE;
    107   virtual void OnStateChanged(
    108       AudioInputIPCDelegate::State state) OVERRIDE;
    109   virtual void OnIPCClosed() OVERRIDE;
    110 
    111  private:
    112   // Note: The ordering of members in this enum is critical to correct behavior!
    113   enum State {
    114     IPC_CLOSED,  // No more IPCs can take place.
    115     IDLE,  // Not started.
    116     CREATING_STREAM,  // Waiting for OnStreamCreated() to be called back.
    117     RECORDING,  // Receiving audio data.
    118   };
    119 
    120   // Methods called on IO thread ----------------------------------------------
    121   // The following methods are tasks posted on the IO thread that needs to
    122   // be executed on that thread. They interact with AudioInputMessageFilter and
    123   // sends IPC messages on that thread.
    124   void StartUpOnIOThread();
    125   void ShutDownOnIOThread();
    126   void SetVolumeOnIOThread(double volume);
    127   void SetAutomaticGainControlOnIOThread(bool enabled);
    128 
    129   // base::MessageLoop::DestructionObserver implementation for the IO loop.
    130   // If the IO loop dies before we do, we shut down the audio thread from here.
    131   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
    132 
    133   AudioParameters audio_parameters_;
    134 
    135   CaptureCallback* callback_;
    136 
    137   // A pointer to the IPC layer that takes care of sending requests over to
    138   // the AudioInputRendererHost.  Only valid when state_ != IPC_CLOSED and must
    139   // only be accessed on the IO thread.
    140   scoped_ptr<AudioInputIPC> ipc_;
    141 
    142   // Current state (must only be accessed from the IO thread).  See comments for
    143   // State enum above.
    144   State state_;
    145 
    146   // The media session ID used to identify which input device to be started.
    147   // Only modified in Initialize() and ShutDownOnIOThread().
    148   int session_id_;
    149 
    150   // Stores the Automatic Gain Control state. Default is false.
    151   // Only modified on the IO thread.
    152   bool agc_is_enabled_;
    153 
    154   // Our audio thread callback class.  See source file for details.
    155   class AudioThreadCallback;
    156 
    157   // In order to avoid a race between OnStreamCreated and Stop(), we use this
    158   // guard to control stopping and starting the audio thread.
    159   base::Lock audio_thread_lock_;
    160   AudioDeviceThread audio_thread_;
    161   scoped_ptr<AudioInputDevice::AudioThreadCallback> audio_callback_;
    162 
    163   // Temporary hack to ignore OnStreamCreated() due to the user calling Stop()
    164   // so we don't start the audio thread pointing to a potentially freed
    165   // |callback_|.
    166   //
    167   // TODO(miu): Replace this by changing AudioCapturerSource to accept the
    168   // callback via Start(). See http://crbug.com/151051 for details.
    169   bool stopping_hack_;
    170 
    171   DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputDevice);
    172 };
    173 
    174 }  // namespace media
    175 
    176 #endif  // MEDIA_AUDIO_AUDIO_INPUT_DEVICE_H_
    177