wavein_input_win.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar// Copyright (c) 2012 The Chromium Authors. All rights reserved.
225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar// Use of this source code is governed by a BSD-style license that can be
325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar// found in the LICENSE file.
425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#ifndef MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#define MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#include <string>
9e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
10e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner#include <windows.h>
11e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner#include <mmsystem.h>
12e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner
1325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#include "base/basictypes.h"
1425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#include "base/compiler_specific.h"
1525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#include "base/synchronization/lock.h"
1625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#include "base/threading/thread_checker.h"
17255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "base/win/scoped_handle.h"
18255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "media/audio/audio_io.h"
1977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter#include "media/audio/audio_parameters.h"
20a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner
2189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolanamespace media {
220855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis
23255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruthclass AudioManagerWin;
24cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar
2584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbarclass PCMWaveInAudioInputStream : public AudioInputStream {
2625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar public:
27baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // The ctor takes all the usual parameters, plus |manager| which is the
28baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // the audio manager who is creating this object and |device_id| which
29baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // is provided by the operating system.
30baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  PCMWaveInAudioInputStream(AudioManagerWin* manager,
31baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling                            const AudioParameters& params,
32baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling                            int num_buffers,
33baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling                            const std::string& device_id);
34320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  virtual ~PCMWaveInAudioInputStream();
35baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
36baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // Implementation of AudioInputStream.
37baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  virtual bool Open() OVERRIDE;
38baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  virtual void Start(AudioInputCallback* callback) OVERRIDE;
39baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  virtual void Stop() OVERRIDE;
40baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  virtual void Close() OVERRIDE;
41baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // TODO(henrika): Add volume support using the Audio Mixer API.
42baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  virtual double GetMaxVolume() OVERRIDE;
43320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  virtual void SetVolume(double volume) OVERRIDE;
44320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  virtual double GetVolume() OVERRIDE;
45320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  virtual void SetAutomaticGainControl(bool enabled) OVERRIDE;
46320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  virtual bool GetAutomaticGainControl() OVERRIDE;
47320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
48320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola private:
49320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  enum State {
50320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateEmpty,      // Initial state.
51320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateReady,      // Device obtained and ready to record.
52320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateRecording,  // Recording audio.
53320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateStopping,   // Trying to stop, waiting for callback to finish.
54320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateStopped,    // Stopped. Device was reset.
55320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    kStateClosed      // Device has been released.
56320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  };
57320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
58320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Allow unit tests to query the device ID.
59320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  friend class AudioManagerTest;
60320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
61320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Windows calls us back with the recorded audio data here. See msdn
62320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // documentation for 'waveInProc' for details about the parameters.
63320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  static void CALLBACK WaveCallback(HWAVEIN hwi, UINT msg, DWORD_PTR instance,
64320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                    DWORD_PTR param1, DWORD_PTR param2);
65320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
66320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // If windows reports an error this function handles it and passes it to
67320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // the attached AudioInputCallback::OnError().
68320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void HandleError(MMRESULT error);
69320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
70320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Allocates and prepares the memory that will be used for recording.
71320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void SetupBuffers();
72320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
73320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Deallocates the memory allocated in SetupBuffers.
74320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void FreeBuffers();
75320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
76320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Sends a buffer to the audio driver for recording.
77320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void QueueNextPacket(WAVEHDR* buffer);
78320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
79320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Converts the stored device id string into an unsigned integer which
80320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // can be used by waveInOpen() to open the specified capture device.
81320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  bool GetDeviceId(UINT* device_index);
82320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
83320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  base::ThreadChecker thread_checker_;
84320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
85320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Reader beware. Visual C has stronger guarantees on volatile vars than
86320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // most people expect. In fact, it has release semantics on write and
87320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // acquire semantics on reads. See the msdn documentation.
88320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  volatile State state_;
89320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
90320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // The audio manager that created this input stream. We notify it when
91320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // we close so it can release its own resources.
92baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  AudioManagerWin* manager_;
93baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
94baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // We use the callback mostly to periodically give the recorded audio data.
95baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  AudioInputCallback* callback_;
96baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
97baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // The number of buffers of size |buffer_size_| each to use.
98baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  const int num_buffers_;
99baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
100baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // The size in bytes of each audio buffer.
101baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  uint32 buffer_size_;
102baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
103320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  // Channels, 1 or 2.
10489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  const int channels_;
105baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
106baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // Contains the unique name of the selected endpoint device.
107dda1bdc962a314bf4fca86f4cd4802ff6c55b172Bill Wendling  // Note that AudioManagerBase::kDefaultDeviceId represents the default
108baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // device role and is not a valid ID as such.
109baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  std::string device_id_;
11038ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
111baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // Windows native structure to encode the format parameters.
112baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  WAVEFORMATEX format_;
113baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
114baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // Handle to the instance of the wave device.
11538ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis  HWAVEIN wavein_;
116baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
117baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  // Pointer to the first allocated audio buffer. This object owns it.
118baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  WAVEHDR* buffer_;
119baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
12084a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar  // An event that is signaled when the callback thread is ready to stop.
121baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling  base::win::ScopedHandle stopped_event_;
1227768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1235cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton  // Lock used to avoid conflicts when Stop() is called during a callback.
1245cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton  base::Lock lock_;
1255cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton
1265cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton  DISALLOW_COPY_AND_ASSIGN(PCMWaveInAudioInputStream);
127baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling};
128baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling
129baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling}  // namespace media
1307768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
131baaefaf828beb3527a3554af99505822fd4dfabfBill Wendling#endif  // MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
132df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne