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// Implementation of AudioInputStream for Windows using Windows Core Audio 6// WASAPI for low latency capturing. 7// 8// Overview of operation: 9// 10// - An object of WASAPIAudioInputStream is created by the AudioManager 11// factory. 12// - Next some thread will call Open(), at that point the underlying 13// Core Audio APIs are utilized to create two WASAPI interfaces called 14// IAudioClient and IAudioCaptureClient. 15// - Then some thread will call Start(sink). 16// A thread called "wasapi_capture_thread" is started and this thread listens 17// on an event signal which is set periodically by the audio engine for 18// each recorded data packet. As a result, data samples will be provided 19// to the registered sink. 20// - At some point, a thread will call Stop(), which stops and joins the 21// capture thread and at the same time stops audio streaming. 22// - The same thread that called stop will call Close() where we cleanup 23// and notify the audio manager, which likely will destroy this object. 24// 25// Implementation notes: 26// 27// - The minimum supported client is Windows Vista. 28// - This implementation is single-threaded, hence: 29// o Construction and destruction must take place from the same thread. 30// o It is recommended to call all APIs from the same thread as well. 31// - It is recommended to first acquire the native sample rate of the default 32// input device and then use the same rate when creating this object. Use 33// WASAPIAudioInputStream::HardwareSampleRate() to retrieve the sample rate. 34// - Calling Close() also leads to self destruction. 35// 36// Core Audio API details: 37// 38// - Utilized MMDevice interfaces: 39// o IMMDeviceEnumerator 40// o IMMDevice 41// - Utilized WASAPI interfaces: 42// o IAudioClient 43// o IAudioCaptureClient 44// - The stream is initialized in shared mode and the processing of the 45// audio buffer is event driven. 46// - The Multimedia Class Scheduler service (MMCSS) is utilized to boost 47// the priority of the capture thread. 48// - Audio applications that use the MMDevice API and WASAPI typically use 49// the ISimpleAudioVolume interface to manage stream volume levels on a 50// per-session basis. It is also possible to use of the IAudioEndpointVolume 51// interface to control the master volume level of an audio endpoint device. 52// This implementation is using the ISimpleAudioVolume interface. 53// MSDN states that "In rare cases, a specialized audio application might 54// require the use of the IAudioEndpointVolume". 55// 56#ifndef MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_INPUT_WIN_H_ 57#define MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_INPUT_WIN_H_ 58 59#include <Audioclient.h> 60#include <MMDeviceAPI.h> 61 62#include <string> 63 64#include "base/compiler_specific.h" 65#include "base/threading/non_thread_safe.h" 66#include "base/threading/platform_thread.h" 67#include "base/threading/simple_thread.h" 68#include "base/win/scoped_co_mem.h" 69#include "base/win/scoped_com_initializer.h" 70#include "base/win/scoped_comptr.h" 71#include "base/win/scoped_handle.h" 72#include "media/audio/agc_audio_stream.h" 73#include "media/audio/audio_parameters.h" 74#include "media/base/media_export.h" 75 76namespace media { 77 78class AudioBus; 79class AudioManagerWin; 80 81// AudioInputStream implementation using Windows Core Audio APIs. 82class MEDIA_EXPORT WASAPIAudioInputStream 83 : public AgcAudioStream<AudioInputStream>, 84 public base::DelegateSimpleThread::Delegate, 85 NON_EXPORTED_BASE(public base::NonThreadSafe) { 86 public: 87 // The ctor takes all the usual parameters, plus |manager| which is the 88 // the audio manager who is creating this object. 89 WASAPIAudioInputStream(AudioManagerWin* manager, 90 const AudioParameters& params, 91 const std::string& device_id); 92 93 // The dtor is typically called by the AudioManager only and it is usually 94 // triggered by calling AudioInputStream::Close(). 95 virtual ~WASAPIAudioInputStream(); 96 97 // Implementation of AudioInputStream. 98 virtual bool Open() OVERRIDE; 99 virtual void Start(AudioInputCallback* callback) OVERRIDE; 100 virtual void Stop() OVERRIDE; 101 virtual void Close() OVERRIDE; 102 virtual double GetMaxVolume() OVERRIDE; 103 virtual void SetVolume(double volume) OVERRIDE; 104 virtual double GetVolume() OVERRIDE; 105 106 bool started() const { return started_; } 107 108 // Returns the default hardware audio parameters of the specific device. 109 static AudioParameters GetInputStreamParameters(const std::string& device_id); 110 111 private: 112 // DelegateSimpleThread::Delegate implementation. 113 virtual void Run() OVERRIDE; 114 115 // Issues the OnError() callback to the |sink_|. 116 void HandleError(HRESULT err); 117 118 // The Open() method is divided into these sub methods. 119 HRESULT SetCaptureDevice(); 120 HRESULT ActivateCaptureDevice(); 121 HRESULT GetAudioEngineStreamFormat(); 122 bool DesiredFormatIsSupported(); 123 HRESULT InitializeAudioEngine(); 124 125 // Retrieves the stream format that the audio engine uses for its internal 126 // processing/mixing of shared-mode streams. 127 // |effects| is a an AudioParameters::effects() flag that will have the 128 // DUCKING flag raised for only the default communication device. 129 static HRESULT GetMixFormat(const std::string& device_id, 130 WAVEFORMATEX** device_format, 131 int* effects); 132 133 // Our creator, the audio manager needs to be notified when we close. 134 AudioManagerWin* manager_; 135 136 // Capturing is driven by this thread (which has no message loop). 137 // All OnData() callbacks will be called from this thread. 138 base::DelegateSimpleThread* capture_thread_; 139 140 // Contains the desired audio format which is set up at construction. 141 WAVEFORMATEX format_; 142 143 bool opened_; 144 bool started_; 145 146 // Size in bytes of each audio frame (4 bytes for 16-bit stereo PCM) 147 size_t frame_size_; 148 149 // Size in audio frames of each audio packet where an audio packet 150 // is defined as the block of data which the user received in each 151 // OnData() callback. 152 size_t packet_size_frames_; 153 154 // Size in bytes of each audio packet. 155 size_t packet_size_bytes_; 156 157 // Length of the audio endpoint buffer. 158 uint32 endpoint_buffer_size_frames_; 159 160 // A copy of the supplied AudioParameter's |effects|. 161 const int effects_; 162 163 // Contains the unique name of the selected endpoint device. 164 // Note that AudioManagerBase::kDefaultDeviceId represents the default 165 // device role and is not a valid ID as such. 166 std::string device_id_; 167 168 // Conversion factor used in delay-estimation calculations. 169 // Converts a raw performance counter value to 100-nanosecond unit. 170 double perf_count_to_100ns_units_; 171 172 // Conversion factor used in delay-estimation calculations. 173 // Converts from milliseconds to audio frames. 174 double ms_to_frame_count_; 175 176 // Pointer to the object that will receive the recorded audio samples. 177 AudioInputCallback* sink_; 178 179 // Windows Multimedia Device (MMDevice) API interfaces. 180 181 // An IMMDevice interface which represents an audio endpoint device. 182 base::win::ScopedComPtr<IMMDevice> endpoint_device_; 183 184 // Windows Audio Session API (WASAPI) interfaces. 185 186 // An IAudioClient interface which enables a client to create and initialize 187 // an audio stream between an audio application and the audio engine. 188 base::win::ScopedComPtr<IAudioClient> audio_client_; 189 190 // Loopback IAudioClient doesn't support event-driven mode, so a separate 191 // IAudioClient is needed to receive notifications when data is available in 192 // the buffer. For loopback input |audio_client_| is used to receive data, 193 // while |audio_render_client_for_loopback_| is used to get notifications 194 // when a new buffer is ready. See comment in InitializeAudioEngine() for 195 // details. 196 base::win::ScopedComPtr<IAudioClient> audio_render_client_for_loopback_; 197 198 // The IAudioCaptureClient interface enables a client to read input data 199 // from a capture endpoint buffer. 200 base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_; 201 202 // The ISimpleAudioVolume interface enables a client to control the 203 // master volume level of an audio session. 204 // The volume-level is a value in the range 0.0 to 1.0. 205 // This interface does only work with shared-mode streams. 206 base::win::ScopedComPtr<ISimpleAudioVolume> simple_audio_volume_; 207 208 // The audio engine will signal this event each time a buffer has been 209 // recorded. 210 base::win::ScopedHandle audio_samples_ready_event_; 211 212 // This event will be signaled when capturing shall stop. 213 base::win::ScopedHandle stop_capture_event_; 214 215 // Extra audio bus used for storage of deinterleaved data for the OnData 216 // callback. 217 scoped_ptr<media::AudioBus> audio_bus_; 218 219 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioInputStream); 220}; 221 222} // namespace media 223 224#endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_INPUT_WIN_H_ 225