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 76 namespace media { 77 78 class AudioManagerWin; 79 80 // AudioInputStream implementation using Windows Core Audio APIs. 81 class MEDIA_EXPORT WASAPIAudioInputStream 82 : public AgcAudioStream<AudioInputStream>, 83 public base::DelegateSimpleThread::Delegate, 84 NON_EXPORTED_BASE(public base::NonThreadSafe) { 85 public: 86 // The ctor takes all the usual parameters, plus |manager| which is the 87 // the audio manager who is creating this object. 88 WASAPIAudioInputStream(AudioManagerWin* manager, 89 const AudioParameters& params, 90 const std::string& device_id); 91 // The dtor is typically called by the AudioManager only and it is usually 92 // triggered by calling AudioInputStream::Close(). 93 virtual ~WASAPIAudioInputStream(); 94 95 // Implementation of AudioInputStream. 96 virtual bool Open() OVERRIDE; 97 virtual void Start(AudioInputCallback* callback) OVERRIDE; 98 virtual void Stop() OVERRIDE; 99 virtual void Close() OVERRIDE; 100 virtual double GetMaxVolume() OVERRIDE; 101 virtual void SetVolume(double volume) OVERRIDE; 102 virtual double GetVolume() OVERRIDE; 103 104 // Retrieves the sample rate used by the audio engine for its internal 105 // processing/mixing of shared-mode streams given a specifed device. 106 static int HardwareSampleRate(const std::string& device_id); 107 108 // Retrieves the number of audio channels used by the audio engine for its 109 // internal processing/mixing of shared-mode streams given a specified device. 110 static uint32 HardwareChannelCount(const std::string& device_id); 111 112 bool started() const { return started_; } 113 114 private: 115 // DelegateSimpleThread::Delegate implementation. 116 virtual void Run() OVERRIDE; 117 118 // Issues the OnError() callback to the |sink_|. 119 void HandleError(HRESULT err); 120 121 // The Open() method is divided into these sub methods. 122 HRESULT SetCaptureDevice(); 123 HRESULT ActivateCaptureDevice(); 124 HRESULT GetAudioEngineStreamFormat(); 125 bool DesiredFormatIsSupported(); 126 HRESULT InitializeAudioEngine(); 127 128 // Retrieves the stream format that the audio engine uses for its internal 129 // processing/mixing of shared-mode streams. 130 static HRESULT GetMixFormat(const std::string& device_id, 131 WAVEFORMATEX** device_format); 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 // Contains the unique name of the selected endpoint device. 161 // Note that AudioManagerBase::kDefaultDeviceId represents the default 162 // device role and is not a valid ID as such. 163 std::string device_id_; 164 165 // Conversion factor used in delay-estimation calculations. 166 // Converts a raw performance counter value to 100-nanosecond unit. 167 double perf_count_to_100ns_units_; 168 169 // Conversion factor used in delay-estimation calculations. 170 // Converts from milliseconds to audio frames. 171 double ms_to_frame_count_; 172 173 // Pointer to the object that will receive the recorded audio samples. 174 AudioInputCallback* sink_; 175 176 // Windows Multimedia Device (MMDevice) API interfaces. 177 178 // An IMMDevice interface which represents an audio endpoint device. 179 base::win::ScopedComPtr<IMMDevice> endpoint_device_; 180 181 // Windows Audio Session API (WASAP) interfaces. 182 183 // An IAudioClient interface which enables a client to create and initialize 184 // an audio stream between an audio application and the audio engine. 185 base::win::ScopedComPtr<IAudioClient> audio_client_; 186 187 // Loopback IAudioClient doesn't support event-driven mode, so a separate 188 // IAudioClient is needed to receive notifications when data is available in 189 // the buffer. For loopback input |audio_client_| is used to receive data, 190 // while |audio_render_client_for_loopback_| is used to get notifications 191 // when a new buffer is ready. See comment in InitializeAudioEngine() for 192 // details. 193 base::win::ScopedComPtr<IAudioClient> audio_render_client_for_loopback_; 194 195 // The IAudioCaptureClient interface enables a client to read input data 196 // from a capture endpoint buffer. 197 base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_; 198 199 // The ISimpleAudioVolume interface enables a client to control the 200 // master volume level of an audio session. 201 // The volume-level is a value in the range 0.0 to 1.0. 202 // This interface does only work with shared-mode streams. 203 base::win::ScopedComPtr<ISimpleAudioVolume> simple_audio_volume_; 204 205 // The audio engine will signal this event each time a buffer has been 206 // recorded. 207 base::win::ScopedHandle audio_samples_ready_event_; 208 209 // This event will be signaled when capturing shall stop. 210 base::win::ScopedHandle stop_capture_event_; 211 212 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioInputStream); 213 }; 214 215 } // namespace media 216 217 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_INPUT_WIN_H_ 218