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