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 WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_WAVE_WIN_H 12 #define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_WAVE_WIN_H 13 14 #include "webrtc/base/platform_thread.h" 15 #include "webrtc/modules/audio_device/audio_device_generic.h" 16 #include "webrtc/modules/audio_device/win/audio_mixer_manager_win.h" 17 18 #pragma comment( lib, "winmm.lib" ) 19 20 namespace webrtc { 21 class EventTimerWrapper; 22 class EventWrapper; 23 24 const uint32_t TIMER_PERIOD_MS = 2; 25 const uint32_t REC_CHECK_TIME_PERIOD_MS = 4; 26 const uint16_t REC_PUT_BACK_DELAY = 4; 27 28 const uint32_t N_REC_SAMPLES_PER_SEC = 48000; 29 const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000; 30 31 const uint32_t N_REC_CHANNELS = 1; // default is mono recording 32 const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout 33 34 // NOTE - CPU load will not be correct for other sizes than 10ms 35 const uint32_t REC_BUF_SIZE_IN_SAMPLES = (N_REC_SAMPLES_PER_SEC/100); 36 const uint32_t PLAY_BUF_SIZE_IN_SAMPLES = (N_PLAY_SAMPLES_PER_SEC/100); 37 38 enum { N_BUFFERS_IN = 200 }; 39 enum { N_BUFFERS_OUT = 200 }; 40 41 class AudioDeviceWindowsWave : public AudioDeviceGeneric 42 { 43 public: 44 AudioDeviceWindowsWave(const int32_t id); 45 ~AudioDeviceWindowsWave(); 46 47 // Retrieve the currently utilized audio layer 48 virtual int32_t ActiveAudioLayer(AudioDeviceModule::AudioLayer& audioLayer) const; 49 50 // Main initializaton and termination 51 virtual int32_t Init(); 52 virtual int32_t Terminate(); 53 virtual bool Initialized() const; 54 55 // Device enumeration 56 virtual int16_t PlayoutDevices(); 57 virtual int16_t RecordingDevices(); 58 virtual int32_t PlayoutDeviceName( 59 uint16_t index, 60 char name[kAdmMaxDeviceNameSize], 61 char guid[kAdmMaxGuidSize]); 62 virtual int32_t RecordingDeviceName( 63 uint16_t index, 64 char name[kAdmMaxDeviceNameSize], 65 char guid[kAdmMaxGuidSize]); 66 67 // Device selection 68 virtual int32_t SetPlayoutDevice(uint16_t index); 69 virtual int32_t SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device); 70 virtual int32_t SetRecordingDevice(uint16_t index); 71 virtual int32_t SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device); 72 73 // Audio transport initialization 74 virtual int32_t PlayoutIsAvailable(bool& available); 75 virtual int32_t InitPlayout(); 76 virtual bool PlayoutIsInitialized() const; 77 virtual int32_t RecordingIsAvailable(bool& available); 78 virtual int32_t InitRecording(); 79 virtual bool RecordingIsInitialized() const; 80 81 // Audio transport control 82 virtual int32_t StartPlayout(); 83 virtual int32_t StopPlayout(); 84 virtual bool Playing() const; 85 virtual int32_t StartRecording(); 86 virtual int32_t StopRecording(); 87 virtual bool Recording() const; 88 89 // Microphone Automatic Gain Control (AGC) 90 virtual int32_t SetAGC(bool enable); 91 virtual bool AGC() const; 92 93 // Volume control based on the Windows Wave API (Windows only) 94 virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, uint16_t volumeRight); 95 virtual int32_t WaveOutVolume(uint16_t& volumeLeft, uint16_t& volumeRight) const; 96 97 // Audio mixer initialization 98 virtual int32_t InitSpeaker(); 99 virtual bool SpeakerIsInitialized() const; 100 virtual int32_t InitMicrophone(); 101 virtual bool MicrophoneIsInitialized() const; 102 103 // Speaker volume controls 104 virtual int32_t SpeakerVolumeIsAvailable(bool& available); 105 virtual int32_t SetSpeakerVolume(uint32_t volume); 106 virtual int32_t SpeakerVolume(uint32_t& volume) const; 107 virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; 108 virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const; 109 virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const; 110 111 // Microphone volume controls 112 virtual int32_t MicrophoneVolumeIsAvailable(bool& available); 113 virtual int32_t SetMicrophoneVolume(uint32_t volume); 114 virtual int32_t MicrophoneVolume(uint32_t& volume) const; 115 virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const; 116 virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const; 117 virtual int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const; 118 119 // Speaker mute control 120 virtual int32_t SpeakerMuteIsAvailable(bool& available); 121 virtual int32_t SetSpeakerMute(bool enable); 122 virtual int32_t SpeakerMute(bool& enabled) const; 123 124 // Microphone mute control 125 virtual int32_t MicrophoneMuteIsAvailable(bool& available); 126 virtual int32_t SetMicrophoneMute(bool enable); 127 virtual int32_t MicrophoneMute(bool& enabled) const; 128 129 // Microphone boost control 130 virtual int32_t MicrophoneBoostIsAvailable(bool& available); 131 virtual int32_t SetMicrophoneBoost(bool enable); 132 virtual int32_t MicrophoneBoost(bool& enabled) const; 133 134 // Stereo support 135 virtual int32_t StereoPlayoutIsAvailable(bool& available); 136 virtual int32_t SetStereoPlayout(bool enable); 137 virtual int32_t StereoPlayout(bool& enabled) const; 138 virtual int32_t StereoRecordingIsAvailable(bool& available); 139 virtual int32_t SetStereoRecording(bool enable); 140 virtual int32_t StereoRecording(bool& enabled) const; 141 142 // Delay information and control 143 virtual int32_t SetPlayoutBuffer(const AudioDeviceModule::BufferType type, uint16_t sizeMS); 144 virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type, uint16_t& sizeMS) const; 145 virtual int32_t PlayoutDelay(uint16_t& delayMS) const; 146 virtual int32_t RecordingDelay(uint16_t& delayMS) const; 147 148 // CPU load 149 virtual int32_t CPULoad(uint16_t& load) const; 150 151 public: 152 virtual bool PlayoutWarning() const; 153 virtual bool PlayoutError() const; 154 virtual bool RecordingWarning() const; 155 virtual bool RecordingError() const; 156 virtual void ClearPlayoutWarning(); 157 virtual void ClearPlayoutError(); 158 virtual void ClearRecordingWarning(); 159 virtual void ClearRecordingError(); 160 161 public: 162 virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 163 164 private: Lock()165 void Lock() { _critSect.Enter(); }; UnLock()166 void UnLock() { _critSect.Leave(); }; Id()167 int32_t Id() {return _id;} IsUsingOutputDeviceIndex()168 bool IsUsingOutputDeviceIndex() const {return _usingOutputDeviceIndex;} OutputDevice()169 AudioDeviceModule::WindowsDeviceType OutputDevice() const {return _outputDevice;} OutputDeviceIndex()170 uint16_t OutputDeviceIndex() const {return _outputDeviceIndex;} IsUsingInputDeviceIndex()171 bool IsUsingInputDeviceIndex() const {return _usingInputDeviceIndex;} InputDevice()172 AudioDeviceModule::WindowsDeviceType InputDevice() const {return _inputDevice;} InputDeviceIndex()173 uint16_t InputDeviceIndex() const {return _inputDeviceIndex;} 174 175 private: 176 inline int32_t InputSanityCheckAfterUnlockedPeriod() const; 177 inline int32_t OutputSanityCheckAfterUnlockedPeriod() const; 178 179 private: 180 bool KeyPressed() const; 181 182 private: 183 int32_t EnumeratePlayoutDevices(); 184 int32_t EnumerateRecordingDevices(); 185 void TraceSupportFlags(DWORD dwSupport) const; 186 void TraceWaveInError(MMRESULT error) const; 187 void TraceWaveOutError(MMRESULT error) const; 188 int32_t PrepareStartRecording(); 189 int32_t PrepareStartPlayout(); 190 191 int32_t RecProc(LONGLONG& consumedTime); 192 int PlayProc(LONGLONG& consumedTime); 193 194 int32_t GetPlayoutBufferDelay(uint32_t& writtenSamples, uint32_t& playedSamples); 195 int32_t GetRecordingBufferDelay(uint32_t& readSamples, uint32_t& recSamples); 196 int32_t Write(int8_t* data, uint16_t nSamples); 197 int32_t GetClockDrift(const uint32_t plSamp, const uint32_t rcSamp); 198 int32_t MonitorRecording(const uint32_t time); 199 int32_t RestartTimerIfNeeded(const uint32_t time); 200 201 private: 202 static bool ThreadFunc(void*); 203 bool ThreadProcess(); 204 205 static DWORD WINAPI GetCaptureVolumeThread(LPVOID context); 206 DWORD DoGetCaptureVolumeThread(); 207 208 static DWORD WINAPI SetCaptureVolumeThread(LPVOID context); 209 DWORD DoSetCaptureVolumeThread(); 210 211 private: 212 AudioDeviceBuffer* _ptrAudioBuffer; 213 214 CriticalSectionWrapper& _critSect; 215 EventTimerWrapper& _timeEvent; 216 EventWrapper& _recStartEvent; 217 EventWrapper& _playStartEvent; 218 219 HANDLE _hGetCaptureVolumeThread; 220 HANDLE _hShutdownGetVolumeEvent; 221 HANDLE _hSetCaptureVolumeThread; 222 HANDLE _hShutdownSetVolumeEvent; 223 HANDLE _hSetCaptureVolumeEvent; 224 225 // TODO(pbos): Remove scoped_ptr usage and use PlatformThread directly 226 rtc::scoped_ptr<rtc::PlatformThread> _ptrThread; 227 228 CriticalSectionWrapper& _critSectCb; 229 230 int32_t _id; 231 232 AudioMixerManager _mixerManager; 233 234 bool _usingInputDeviceIndex; 235 bool _usingOutputDeviceIndex; 236 AudioDeviceModule::WindowsDeviceType _inputDevice; 237 AudioDeviceModule::WindowsDeviceType _outputDevice; 238 uint16_t _inputDeviceIndex; 239 uint16_t _outputDeviceIndex; 240 bool _inputDeviceIsSpecified; 241 bool _outputDeviceIsSpecified; 242 243 WAVEFORMATEX _waveFormatIn; 244 WAVEFORMATEX _waveFormatOut; 245 246 HWAVEIN _hWaveIn; 247 HWAVEOUT _hWaveOut; 248 249 WAVEHDR _waveHeaderIn[N_BUFFERS_IN]; 250 WAVEHDR _waveHeaderOut[N_BUFFERS_OUT]; 251 252 uint8_t _recChannels; 253 uint8_t _playChannels; 254 uint16_t _recBufCount; 255 uint16_t _recDelayCount; 256 uint16_t _recPutBackDelay; 257 258 int8_t _recBuffer[N_BUFFERS_IN][4*REC_BUF_SIZE_IN_SAMPLES]; 259 int8_t _playBuffer[N_BUFFERS_OUT][4*PLAY_BUF_SIZE_IN_SAMPLES]; 260 261 AudioDeviceModule::BufferType _playBufType; 262 263 private: 264 bool _initialized; 265 bool _recording; 266 bool _playing; 267 bool _recIsInitialized; 268 bool _playIsInitialized; 269 bool _startRec; 270 bool _stopRec; 271 bool _startPlay; 272 bool _stopPlay; 273 bool _AGC; 274 275 private: 276 uint32_t _prevPlayTime; 277 uint32_t _prevRecTime; 278 uint32_t _prevTimerCheckTime; 279 280 uint16_t _playBufCount; // playout buffer index 281 uint16_t _dTcheckPlayBufDelay; // dT for check of play buffer, {2,5,10} [ms] 282 uint16_t _playBufDelay; // playback delay 283 uint16_t _playBufDelayFixed; // fixed playback delay 284 uint16_t _minPlayBufDelay; // minimum playback delay 285 uint16_t _MAX_minBuffer; // level of (adaptive) min threshold must be < _MAX_minBuffer 286 287 int32_t _erZeroCounter; // counts "buffer-is-empty" events 288 int32_t _intro; 289 int32_t _waitCounter; 290 291 uint32_t _writtenSamples; 292 uint32_t _writtenSamplesOld; 293 uint32_t _playedSamplesOld; 294 295 uint32_t _sndCardPlayDelay; 296 uint32_t _sndCardRecDelay; 297 298 uint32_t _plSampOld; 299 uint32_t _rcSampOld; 300 301 uint32_t _read_samples; 302 uint32_t _read_samples_old; 303 uint32_t _rec_samples_old; 304 305 // State that detects driver problems: 306 int32_t _dc_diff_mean; 307 int32_t _dc_y_prev; 308 int32_t _dc_penalty_counter; 309 int32_t _dc_prevtime; 310 uint32_t _dc_prevplay; 311 312 uint32_t _recordedBytes; // accumulated #recorded bytes (reset periodically) 313 uint32_t _prevRecByteCheckTime; // time when we last checked the recording process 314 315 // CPU load measurements 316 LARGE_INTEGER _perfFreq; 317 LONGLONG _playAcc; // accumulated time for playout callback 318 float _avgCPULoad; // average total (rec+play) CPU load 319 320 int32_t _wrapCounter; 321 322 int32_t _useHeader; 323 int16_t _timesdwBytes; 324 int32_t _no_of_msecleft_warnings; 325 int32_t _writeErrors; 326 int32_t _timerFaults; 327 int32_t _timerRestartAttempts; 328 329 uint16_t _playWarning; 330 uint16_t _playError; 331 uint16_t _recWarning; 332 uint16_t _recError; 333 334 uint32_t _newMicLevel; 335 uint32_t _minMicVolume; 336 uint32_t _maxMicVolume; 337 }; 338 339 } // namespace webrtc 340 341 #endif // WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_WAVE_WIN_H 342