1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef MODULES_AUDIO_DEVICE_WIN_AUDIO_DEVICE_CORE_WIN_H_ 12 #define MODULES_AUDIO_DEVICE_WIN_AUDIO_DEVICE_CORE_WIN_H_ 13 14 #if (_MSC_VER >= 1400) // only include for VS 2005 and higher 15 16 #include "rtc_base/win32.h" 17 18 #include "modules/audio_device/audio_device_generic.h" 19 20 #include <wmcodecdsp.h> // CLSID_CWMAudioAEC 21 // (must be before audioclient.h) 22 #include <audioclient.h> // WASAPI 23 #include <audiopolicy.h> 24 #include <avrt.h> // Avrt 25 #include <endpointvolume.h> 26 #include <mediaobj.h> // IMediaObject 27 #include <mmdeviceapi.h> // MMDevice 28 29 #include "api/scoped_refptr.h" 30 #include "rtc_base/synchronization/mutex.h" 31 #include "rtc_base/win/scoped_com_initializer.h" 32 33 // Use Multimedia Class Scheduler Service (MMCSS) to boost the thread priority 34 #pragma comment(lib, "avrt.lib") 35 // AVRT function pointers 36 typedef BOOL(WINAPI* PAvRevertMmThreadCharacteristics)(HANDLE); 37 typedef HANDLE(WINAPI* PAvSetMmThreadCharacteristicsA)(LPCSTR, LPDWORD); 38 typedef BOOL(WINAPI* PAvSetMmThreadPriority)(HANDLE, AVRT_PRIORITY); 39 40 namespace webrtc { 41 42 const float MAX_CORE_SPEAKER_VOLUME = 255.0f; 43 const float MIN_CORE_SPEAKER_VOLUME = 0.0f; 44 const float MAX_CORE_MICROPHONE_VOLUME = 255.0f; 45 const float MIN_CORE_MICROPHONE_VOLUME = 0.0f; 46 const uint16_t CORE_SPEAKER_VOLUME_STEP_SIZE = 1; 47 const uint16_t CORE_MICROPHONE_VOLUME_STEP_SIZE = 1; 48 49 class AudioDeviceWindowsCore : public AudioDeviceGeneric { 50 public: 51 AudioDeviceWindowsCore(); 52 ~AudioDeviceWindowsCore(); 53 54 static bool CoreAudioIsSupported(); 55 56 // Retrieve the currently utilized audio layer 57 virtual int32_t ActiveAudioLayer( 58 AudioDeviceModule::AudioLayer& audioLayer) const; 59 60 // Main initializaton and termination 61 virtual InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_); 62 virtual int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_); 63 virtual bool Initialized() const; 64 65 // Device enumeration 66 virtual int16_t PlayoutDevices() RTC_LOCKS_EXCLUDED(mutex_); 67 virtual int16_t RecordingDevices() RTC_LOCKS_EXCLUDED(mutex_); 68 virtual int32_t PlayoutDeviceName(uint16_t index, 69 char name[kAdmMaxDeviceNameSize], 70 char guid[kAdmMaxGuidSize]) 71 RTC_LOCKS_EXCLUDED(mutex_); 72 virtual int32_t RecordingDeviceName(uint16_t index, 73 char name[kAdmMaxDeviceNameSize], 74 char guid[kAdmMaxGuidSize]) 75 RTC_LOCKS_EXCLUDED(mutex_); 76 77 // Device selection 78 virtual int32_t SetPlayoutDevice(uint16_t index) RTC_LOCKS_EXCLUDED(mutex_); 79 virtual int32_t SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device); 80 virtual int32_t SetRecordingDevice(uint16_t index) RTC_LOCKS_EXCLUDED(mutex_); 81 virtual int32_t SetRecordingDevice( 82 AudioDeviceModule::WindowsDeviceType device) RTC_LOCKS_EXCLUDED(mutex_); 83 84 // Audio transport initialization 85 virtual int32_t PlayoutIsAvailable(bool& available); 86 virtual int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_); 87 virtual bool PlayoutIsInitialized() const; 88 virtual int32_t RecordingIsAvailable(bool& available); 89 virtual int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_); 90 virtual bool RecordingIsInitialized() const; 91 92 // Audio transport control 93 virtual int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_); 94 virtual int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_); 95 virtual bool Playing() const; 96 virtual int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_); 97 virtual int32_t StopRecording(); 98 virtual bool Recording() const; 99 100 // Audio mixer initialization 101 virtual int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_); 102 virtual bool SpeakerIsInitialized() const; 103 virtual int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_); 104 virtual bool MicrophoneIsInitialized() const; 105 106 // Speaker volume controls 107 virtual int32_t SpeakerVolumeIsAvailable(bool& available) 108 RTC_LOCKS_EXCLUDED(mutex_); 109 virtual int32_t SetSpeakerVolume(uint32_t volume) RTC_LOCKS_EXCLUDED(mutex_); 110 virtual int32_t SpeakerVolume(uint32_t& volume) const 111 RTC_LOCKS_EXCLUDED(mutex_); 112 virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; 113 virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const; 114 115 // Microphone volume controls 116 virtual int32_t MicrophoneVolumeIsAvailable(bool& available) 117 RTC_LOCKS_EXCLUDED(mutex_); 118 virtual int32_t SetMicrophoneVolume(uint32_t volume) 119 RTC_LOCKS_EXCLUDED(mutex_, volume_mutex_); 120 virtual int32_t MicrophoneVolume(uint32_t& volume) const 121 RTC_LOCKS_EXCLUDED(mutex_, volume_mutex_); 122 virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const; 123 virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const; 124 125 // Speaker mute control 126 virtual int32_t SpeakerMuteIsAvailable(bool& available) 127 RTC_LOCKS_EXCLUDED(mutex_); 128 virtual int32_t SetSpeakerMute(bool enable) RTC_LOCKS_EXCLUDED(mutex_); 129 virtual int32_t SpeakerMute(bool& enabled) const; 130 131 // Microphone mute control 132 virtual int32_t MicrophoneMuteIsAvailable(bool& available) 133 RTC_LOCKS_EXCLUDED(mutex_); 134 virtual int32_t SetMicrophoneMute(bool enable); 135 virtual int32_t MicrophoneMute(bool& enabled) const; 136 137 // Stereo support 138 virtual int32_t StereoPlayoutIsAvailable(bool& available); 139 virtual int32_t SetStereoPlayout(bool enable) RTC_LOCKS_EXCLUDED(mutex_); 140 virtual int32_t StereoPlayout(bool& enabled) const; 141 virtual int32_t StereoRecordingIsAvailable(bool& available); 142 virtual int32_t SetStereoRecording(bool enable) RTC_LOCKS_EXCLUDED(mutex_); 143 virtual int32_t StereoRecording(bool& enabled) const 144 RTC_LOCKS_EXCLUDED(mutex_); 145 146 // Delay information and control 147 virtual int32_t PlayoutDelay(uint16_t& delayMS) const 148 RTC_LOCKS_EXCLUDED(mutex_); 149 150 virtual bool BuiltInAECIsAvailable() const; 151 152 virtual int32_t EnableBuiltInAEC(bool enable); 153 154 public: 155 virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 156 157 private: 158 bool KeyPressed() const; 159 160 private: // avrt function pointers 161 PAvRevertMmThreadCharacteristics _PAvRevertMmThreadCharacteristics; 162 PAvSetMmThreadCharacteristicsA _PAvSetMmThreadCharacteristicsA; 163 PAvSetMmThreadPriority _PAvSetMmThreadPriority; 164 HMODULE _avrtLibrary; 165 bool _winSupportAvrt; 166 167 private: // thread functions 168 int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 169 int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 170 int16_t PlayoutDevicesLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 171 int16_t RecordingDevicesLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 172 DWORD InitCaptureThreadPriority(); 173 void RevertCaptureThreadPriority(); 174 static DWORD WINAPI WSAPICaptureThread(LPVOID context); 175 DWORD DoCaptureThread(); 176 177 static DWORD WINAPI WSAPICaptureThreadPollDMO(LPVOID context); 178 DWORD DoCaptureThreadPollDMO() RTC_LOCKS_EXCLUDED(mutex_); 179 180 static DWORD WINAPI WSAPIRenderThread(LPVOID context); 181 DWORD DoRenderThread(); 182 183 void _Lock(); 184 void _UnLock(); 185 186 int SetDMOProperties(); 187 188 int SetBoolProperty(IPropertyStore* ptrPS, 189 REFPROPERTYKEY key, 190 VARIANT_BOOL value); 191 192 int SetVtI4Property(IPropertyStore* ptrPS, REFPROPERTYKEY key, LONG value); 193 194 int32_t _EnumerateEndpointDevicesAll(EDataFlow dataFlow) const; 195 void _TraceCOMError(HRESULT hr) const; 196 197 int32_t _RefreshDeviceList(EDataFlow dir); 198 int16_t _DeviceListCount(EDataFlow dir); 199 int32_t _GetDefaultDeviceName(EDataFlow dir, 200 ERole role, 201 LPWSTR szBuffer, 202 int bufferLen); 203 int32_t _GetListDeviceName(EDataFlow dir, 204 int index, 205 LPWSTR szBuffer, 206 int bufferLen); 207 int32_t _GetDeviceName(IMMDevice* pDevice, LPWSTR pszBuffer, int bufferLen); 208 int32_t _GetListDeviceID(EDataFlow dir, 209 int index, 210 LPWSTR szBuffer, 211 int bufferLen); 212 int32_t _GetDefaultDeviceID(EDataFlow dir, 213 ERole role, 214 LPWSTR szBuffer, 215 int bufferLen); 216 int32_t _GetDefaultDeviceIndex(EDataFlow dir, ERole role, int* index); 217 int32_t _GetDeviceID(IMMDevice* pDevice, LPWSTR pszBuffer, int bufferLen); 218 int32_t _GetDefaultDevice(EDataFlow dir, ERole role, IMMDevice** ppDevice); 219 int32_t _GetListDevice(EDataFlow dir, int index, IMMDevice** ppDevice); 220 221 int32_t InitRecordingDMO(); 222 223 ScopedCOMInitializer _comInit; 224 AudioDeviceBuffer* _ptrAudioBuffer; 225 mutable Mutex mutex_; 226 mutable Mutex volume_mutex_ RTC_ACQUIRED_AFTER(mutex_); 227 228 IMMDeviceEnumerator* _ptrEnumerator; 229 IMMDeviceCollection* _ptrRenderCollection; 230 IMMDeviceCollection* _ptrCaptureCollection; 231 IMMDevice* _ptrDeviceOut; 232 IMMDevice* _ptrDeviceIn; 233 234 IAudioClient* _ptrClientOut; 235 IAudioClient* _ptrClientIn; 236 IAudioRenderClient* _ptrRenderClient; 237 IAudioCaptureClient* _ptrCaptureClient; 238 IAudioEndpointVolume* _ptrCaptureVolume; 239 ISimpleAudioVolume* _ptrRenderSimpleVolume; 240 241 // DirectX Media Object (DMO) for the built-in AEC. 242 rtc::scoped_refptr<IMediaObject> _dmo; 243 rtc::scoped_refptr<IMediaBuffer> _mediaBuffer; 244 bool _builtInAecEnabled; 245 246 HANDLE _hRenderSamplesReadyEvent; 247 HANDLE _hPlayThread; 248 HANDLE _hRenderStartedEvent; 249 HANDLE _hShutdownRenderEvent; 250 251 HANDLE _hCaptureSamplesReadyEvent; 252 HANDLE _hRecThread; 253 HANDLE _hCaptureStartedEvent; 254 HANDLE _hShutdownCaptureEvent; 255 256 HANDLE _hMmTask; 257 258 UINT _playAudioFrameSize; 259 uint32_t _playSampleRate; 260 uint32_t _devicePlaySampleRate; 261 uint32_t _playBlockSize; 262 uint32_t _devicePlayBlockSize; 263 uint32_t _playChannels; 264 uint32_t _sndCardPlayDelay; 265 UINT64 _writtenSamples; 266 UINT64 _readSamples; 267 268 UINT _recAudioFrameSize; 269 uint32_t _recSampleRate; 270 uint32_t _recBlockSize; 271 uint32_t _recChannels; 272 273 uint16_t _recChannelsPrioList[3]; 274 uint16_t _playChannelsPrioList[2]; 275 276 LARGE_INTEGER _perfCounterFreq; 277 double _perfCounterFactor; 278 279 private: 280 bool _initialized; 281 bool _recording; 282 bool _playing; 283 bool _recIsInitialized; 284 bool _playIsInitialized; 285 bool _speakerIsInitialized; 286 bool _microphoneIsInitialized; 287 288 bool _usingInputDeviceIndex; 289 bool _usingOutputDeviceIndex; 290 AudioDeviceModule::WindowsDeviceType _inputDevice; 291 AudioDeviceModule::WindowsDeviceType _outputDevice; 292 uint16_t _inputDeviceIndex; 293 uint16_t _outputDeviceIndex; 294 }; 295 296 #endif // #if (_MSC_VER >= 1400) 297 298 } // namespace webrtc 299 300 #endif // MODULES_AUDIO_DEVICE_WIN_AUDIO_DEVICE_CORE_WIN_H_ 301