Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / media / audio / audio_input_controller.h
index 6b40459..691f1af 100644 (file)
@@ -16,6 +16,9 @@
 #include "base/timer/timer.h"
 #include "media/audio/audio_io.h"
 #include "media/audio/audio_manager_base.h"
+#include "media/audio/audio_parameters.h"
+#include "media/audio/audio_power_monitor.h"
+#include "media/base/audio_bus.h"
 
 // An AudioInputController controls an AudioInputStream and records data
 // from this input stream. The two main methods are Record() and Close() and
 //
 namespace media {
 
+// Only do power monitoring for non-mobile platforms to save resources.
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+#define AUDIO_POWER_MONITORING
+#endif
+
 class UserInputMonitor;
 
 class MEDIA_EXPORT AudioInputController
     : public base::RefCountedThreadSafe<AudioInputController>,
       public AudioInputStream::AudioInputCallback {
  public:
+
+  // Error codes to make native loggin more clear. These error codes are added
+  // to generic error strings to provide a higher degree of details.
+  // Changing these values can lead to problems when matching native debug
+  // logs with the actual cause of error.
+  enum ErrorCode {
+    // An unspecified error occured.
+    UNKNOWN_ERROR = 0,
+
+    // Failed to create an audio input stream.
+    STREAM_CREATE_ERROR,  // = 1
+
+    // Failed to open an audio input stream.
+    STREAM_OPEN_ERROR,  // = 2
+
+    // Native input stream reports an error. Exact reason differs between
+    // platforms.
+    STREAM_ERROR,  // = 3
+
+    // This can happen if a capture device has been removed or disabled.
+    NO_DATA_ERROR,  // = 4
+  };
+
   // An event handler that receives events from the AudioInputController. The
   // following methods are all called on the audio thread.
   class MEDIA_EXPORT EventHandler {
    public:
     virtual void OnCreated(AudioInputController* controller) = 0;
     virtual void OnRecording(AudioInputController* controller) = 0;
-    virtual void OnError(AudioInputController* controller) = 0;
-    virtual void OnData(AudioInputController* controller, const uint8* data,
-                        uint32 size) = 0;
+    virtual void OnError(AudioInputController* controller,
+                         ErrorCode error_code) = 0;
+    virtual void OnData(AudioInputController* controller,
+                        const AudioBus* data) = 0;
+    virtual void OnLog(AudioInputController* controller,
+                       const std::string& message) = 0;
 
    protected:
     virtual ~EventHandler() {}
@@ -102,12 +136,10 @@ class MEDIA_EXPORT AudioInputController
     // soundcard which has been recorded.
     virtual void UpdateRecordedBytes(uint32 bytes) = 0;
 
-    // Write certain amount of data from |data|. This method returns
-    // number of written bytes.
-    virtual uint32 Write(const void* data,
-                         uint32 size,
-                         double volume,
-                         bool key_pressed) = 0;
+    // Write certain amount of data from |data|.
+    virtual void Write(const AudioBus* data,
+                       double volume,
+                       bool key_pressed) = 0;
 
     // Close this synchronous writer.
     virtual void Close() = 0;
@@ -159,13 +191,13 @@ class MEDIA_EXPORT AudioInputController
       SyncWriter* sync_writer,
       UserInputMonitor* user_input_monitor);
 
-  // Factory method for creating an AudioInputController for low-latency mode,
-  // taking ownership of |stream|.  The stream will be opened on the audio
-  // thread, and when that is done, the event handler will receive an
-  // OnCreated() call from that same thread. |user_input_monitor| is used for
-  // typing detection and can be NULL.
+  // Factory method for creating an AudioInputController with an existing
+  // |stream| for low-latency mode, taking ownership of |stream|. The stream
+  // will be opened on the audio thread, and when that is done, the event
+  // handler will receive an OnCreated() call from that same thread.
+  // |user_input_monitor| is used for typing detection and can be NULL.
   static scoped_refptr<AudioInputController> CreateForStream(
-      const scoped_refptr<base::MessageLoopProxy>& message_loop,
+      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       EventHandler* event_handler,
       AudioInputStream* stream,
       // External synchronous writer for audio controller.
@@ -196,57 +228,93 @@ class MEDIA_EXPORT AudioInputController
 
   // AudioInputCallback implementation. Threading details depends on the
   // device-specific implementation.
-  virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size,
-                      uint32 hardware_delay_bytes, double volume) OVERRIDE;
-  virtual void OnClose(AudioInputStream* stream) OVERRIDE;
+  virtual void OnData(AudioInputStream* stream,
+                      const AudioBus* source,
+                      uint32 hardware_delay_bytes,
+                      double volume) OVERRIDE;
   virtual void OnError(AudioInputStream* stream) OVERRIDE;
 
-  bool LowLatencyMode() const { return sync_writer_ != NULL; }
+  bool SharedMemoryAndSyncSocketMode() const { return sync_writer_ != NULL; }
 
  protected:
   friend class base::RefCountedThreadSafe<AudioInputController>;
 
   // Internal state of the source.
   enum State {
-    kEmpty,
-    kCreated,
-    kRecording,
-    kClosed,
-    kError
+    CREATED,
+    RECORDING,
+    CLOSED
   };
 
+#if defined(AUDIO_POWER_MONITORING)
+  // Used to log a silence report (see OnData).
+  // Elements in this enum should not be deleted or rearranged; the only
+  // permitted operation is to add new elements before SILENCE_STATE_MAX and
+  // update SILENCE_STATE_MAX.
+  // Possible silence state transitions:
+  //           SILENCE_STATE_AUDIO_AND_SILENCE
+  //               ^                  ^
+  // SILENCE_STATE_ONLY_AUDIO   SILENCE_STATE_ONLY_SILENCE
+  //               ^                  ^
+  //            SILENCE_STATE_NO_MEASUREMENT
+  enum SilenceState {
+    SILENCE_STATE_NO_MEASUREMENT = 0,
+    SILENCE_STATE_ONLY_AUDIO = 1,
+    SILENCE_STATE_ONLY_SILENCE = 2,
+    SILENCE_STATE_AUDIO_AND_SILENCE = 3,
+    SILENCE_STATE_MAX = SILENCE_STATE_AUDIO_AND_SILENCE
+  };
+#endif
+
   AudioInputController(EventHandler* handler,
                        SyncWriter* sync_writer,
                        UserInputMonitor* user_input_monitor);
   virtual ~AudioInputController();
 
   // Methods called on the audio thread (owned by the AudioManager).
-  void DoCreate(AudioManager* audio_manager, const AudioParameters& params,
+  void DoCreate(AudioManager* audio_manager,
+                const AudioParameters& params,
                 const std::string& device_id);
-  void DoCreateForStream(AudioInputStream* stream_to_control,
-                         bool enable_nodata_timer);
+  void DoCreateForLowLatency(AudioManager* audio_manager,
+                             const AudioParameters& params,
+                             const std::string& device_id);
+  void DoCreateForStream(AudioInputStream* stream_to_control);
   void DoRecord();
   void DoClose();
   void DoReportError();
   void DoSetVolume(double volume);
   void DoSetAutomaticGainControl(bool enabled);
+  void DoOnData(scoped_ptr<AudioBus> data);
+  void DoLogAudioLevel(float level_dbfs);
+
+  // Method to check if we get recorded data after a stream was started,
+  // and log the result to UMA.
+  void FirstCheckForNoData();
 
   // Method which ensures that OnError() is triggered when data recording
   // times out. Called on the audio thread.
   void DoCheckForNoData();
 
   // Helper method that stops, closes, and NULL:s |*stream_|.
-  // Signals event when done if the event is not NULL.
-  void DoStopCloseAndClearStream(base::WaitableEvent* done);
+  void DoStopCloseAndClearStream();
 
   void SetDataIsActive(bool enabled);
   bool GetDataIsActive();
 
-  // Gives access to the message loop of the creating thread.
-  scoped_refptr<base::MessageLoopProxy> creator_loop_;
+#if defined(AUDIO_POWER_MONITORING)
+  // Updates the silence state, see enum SilenceState above for state
+  // transitions.
+  void UpdateSilenceState(bool silence);
+
+  // Logs the silence state as UMA stat.
+  void LogSilenceState(SilenceState value);
+#endif
+
+  // Gives access to the task runner of the creating thread.
+  scoped_refptr<base::SingleThreadTaskRunner> creator_task_runner_;
 
-  // The message loop of audio-manager thread that this object runs on.
-  scoped_refptr<base::MessageLoopProxy> message_loop_;
+  // The task runner of audio-manager thread that this object runs on.
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   // Contains the AudioInputController::EventHandler which receives state
   // notifications from this class.
@@ -256,8 +324,8 @@ class MEDIA_EXPORT AudioInputController
   AudioInputStream* stream_;
 
   // |no_data_timer_| is used to call OnError() when we stop receiving
-  // OnData() calls without an OnClose() call. This can occur
-  // when an audio input device is unplugged whilst recording on Windows.
+  // OnData() calls. This can occur when an audio input device is unplugged
+  // whilst recording on Windows.
   // See http://crbug.com/79936 for details.
   // This member is only touched by the audio thread.
   scoped_ptr<base::Timer> no_data_timer_;
@@ -284,6 +352,21 @@ class MEDIA_EXPORT AudioInputController
 
   UserInputMonitor* user_input_monitor_;
 
+#if defined(AUDIO_POWER_MONITORING)
+  // Scans audio samples from OnData() as input to compute audio levels.
+  scoped_ptr<AudioPowerMonitor> audio_level_;
+
+  // We need these to be able to feed data to the AudioPowerMonitor.
+  media::AudioParameters audio_params_;
+  base::TimeTicks last_audio_level_log_time_;
+
+  // Whether the silence state should sent as UMA stat.
+  bool log_silence_state_;
+
+  // The silence report sent as UMA stat at the end of a session.
+  SilenceState silence_state_;
+#endif
+
   size_t prev_key_down_count_;
 
   DISALLOW_COPY_AND_ASSIGN(AudioInputController);