audio_capturer_win.cc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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. #include "remoting/host/audio_capturer_win.h"
  5. #include <avrt.h>
  6. #include <mmreg.h>
  7. #include <mmsystem.h>
  8. #include <objbase.h>
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <windows.h>
  12. #include <algorithm>
  13. #include <memory>
  14. #include <utility>
  15. #include "base/logging.h"
  16. #include "base/memory/ptr_util.h"
  17. #include "base/synchronization/lock.h"
  18. #include "remoting/host/win/default_audio_device_change_detector.h"
  19. namespace {
  20. const int kBytesPerSample = 2;
  21. const int kBitsPerSample = kBytesPerSample * 8;
  22. // Conversion factor from 100ns to 1ms.
  23. const int k100nsPerMillisecond = 10000;
  24. // Tolerance for catching packets of silence. If all samples have absolute
  25. // value less than this threshold, the packet will be counted as a packet of
  26. // silence. A value of 2 was chosen, because Windows can give samples of 1 and
  27. // -1, even when no audio is playing.
  28. const int kSilenceThreshold = 2;
  29. // Lower bound for timer intervals, in milliseconds.
  30. const int kMinTimerInterval = 30;
  31. // Upper bound for the timer precision error, in milliseconds.
  32. // Timers are supposed to be accurate to 20ms, so we use 30ms to be safe.
  33. const int kMaxExpectedTimerLag = 30;
  34. } // namespace
  35. namespace remoting {
  36. AudioCapturerWin::AudioCapturerWin()
  37. : sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID),
  38. volume_filter_(kSilenceThreshold),
  39. last_capture_error_(S_OK) {
  40. thread_checker_.DetachFromThread();
  41. }
  42. AudioCapturerWin::~AudioCapturerWin() {
  43. DCHECK(thread_checker_.CalledOnValidThread());
  44. Deinitialize();
  45. }
  46. bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) {
  47. callback_ = callback;
  48. if (!Initialize()) {
  49. return false;
  50. }
  51. // Initialize the capture timer and start capturing. Note, this timer won't
  52. // be reset or restarted in ResetAndInitialize() function. Which means we
  53. // expect the audio_device_period_ is a system wide configuration, it would
  54. // not be changed with the default audio device.
  55. capture_timer_ = std::make_unique<base::RepeatingTimer>();
  56. capture_timer_->Start(FROM_HERE, audio_device_period_, this,
  57. &AudioCapturerWin::DoCapture);
  58. return true;
  59. }
  60. bool AudioCapturerWin::ResetAndInitialize() {
  61. Deinitialize();
  62. if (!Initialize()) {
  63. Deinitialize();
  64. return false;
  65. }
  66. return true;
  67. }
  68. void AudioCapturerWin::Deinitialize() {
  69. DCHECK(thread_checker_.CalledOnValidThread());
  70. wave_format_ex_.Reset(nullptr);
  71. default_device_detector_.reset();
  72. audio_capture_client_.Reset();
  73. if (audio_client_) {
  74. audio_client_->Stop();
  75. }
  76. audio_client_.Reset();
  77. mm_device_.Reset();
  78. }
  79. bool AudioCapturerWin::Initialize() {
  80. DCHECK(!audio_capture_client_.Get());
  81. DCHECK(!audio_client_.Get());
  82. DCHECK(!mm_device_.Get());
  83. DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == nullptr);
  84. DCHECK(thread_checker_.CalledOnValidThread());
  85. HRESULT hr = S_OK;
  86. Microsoft::WRL::ComPtr<IMMDeviceEnumerator> mm_device_enumerator;
  87. hr = ::CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
  88. IID_PPV_ARGS(&mm_device_enumerator));
  89. if (FAILED(hr)) {
  90. LOG(ERROR) << "Failed to create IMMDeviceEnumerator. Error " << hr;
  91. return false;
  92. }
  93. default_device_detector_ =
  94. std::make_unique<DefaultAudioDeviceChangeDetector>(mm_device_enumerator);
  95. // Get the audio endpoint.
  96. hr = mm_device_enumerator->GetDefaultAudioEndpoint(eRender, eConsole,
  97. &mm_device_);
  98. if (FAILED(hr)) {
  99. LOG(ERROR) << "Failed to get IMMDevice. Error " << hr;
  100. return false;
  101. }
  102. // Get an audio client.
  103. hr = mm_device_->Activate(__uuidof(IAudioClient),
  104. CLSCTX_ALL,
  105. nullptr,
  106. &audio_client_);
  107. if (FAILED(hr)) {
  108. LOG(ERROR) << "Failed to get an IAudioClient. Error " << hr;
  109. return false;
  110. }
  111. REFERENCE_TIME device_period;
  112. hr = audio_client_->GetDevicePeriod(&device_period, nullptr);
  113. if (FAILED(hr)) {
  114. LOG(ERROR) << "IAudioClient::GetDevicePeriod failed. Error " << hr;
  115. return false;
  116. }
  117. // We round up, if |device_period| / |k100nsPerMillisecond|
  118. // is not a whole number.
  119. int device_period_in_milliseconds =
  120. 1 + ((device_period - 1) / k100nsPerMillisecond);
  121. audio_device_period_ = base::Milliseconds(
  122. std::max(device_period_in_milliseconds, kMinTimerInterval));
  123. // Get the wave format.
  124. hr = audio_client_->GetMixFormat(&wave_format_ex_);
  125. if (FAILED(hr)) {
  126. LOG(ERROR) << "Failed to get WAVEFORMATEX. Error " << hr;
  127. return false;
  128. }
  129. if (wave_format_ex_->wFormatTag != WAVE_FORMAT_IEEE_FLOAT &&
  130. wave_format_ex_->wFormatTag != WAVE_FORMAT_PCM &&
  131. wave_format_ex_->wFormatTag != WAVE_FORMAT_EXTENSIBLE) {
  132. LOG(ERROR) << "Failed to force 16-bit PCM";
  133. return false;
  134. }
  135. if (!AudioCapturer::IsValidSampleRate(wave_format_ex_->nSamplesPerSec)) {
  136. LOG(ERROR) << "Host sampling rate is neither 44.1 kHz nor 48 kHz. "
  137. << wave_format_ex_->nSamplesPerSec;
  138. return false;
  139. }
  140. // We support from mono to 7.1. This check should be consistent with
  141. // AudioPacket::Channels.
  142. if (wave_format_ex_->nChannels > 8 || wave_format_ex_->nChannels <= 0) {
  143. LOG(ERROR) << "Unsupported channels " << wave_format_ex_->nChannels;
  144. return false;
  145. }
  146. sampling_rate_ = static_cast<AudioPacket::SamplingRate>(
  147. wave_format_ex_->nSamplesPerSec);
  148. wave_format_ex_->wBitsPerSample = kBitsPerSample;
  149. wave_format_ex_->nBlockAlign = wave_format_ex_->nChannels * kBytesPerSample;
  150. wave_format_ex_->nAvgBytesPerSec =
  151. sampling_rate_ * wave_format_ex_->nBlockAlign;
  152. if (wave_format_ex_->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
  153. PWAVEFORMATEXTENSIBLE wave_format_extensible =
  154. reinterpret_cast<WAVEFORMATEXTENSIBLE*>(
  155. static_cast<WAVEFORMATEX*>(wave_format_ex_));
  156. if (!IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
  157. wave_format_extensible->SubFormat) &&
  158. !IsEqualGUID(KSDATAFORMAT_SUBTYPE_PCM,
  159. wave_format_extensible->SubFormat)) {
  160. LOG(ERROR) << "Failed to force 16-bit samples";
  161. return false;
  162. }
  163. wave_format_extensible->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
  164. wave_format_extensible->Samples.wValidBitsPerSample = kBitsPerSample;
  165. } else {
  166. wave_format_ex_->wFormatTag = WAVE_FORMAT_PCM;
  167. }
  168. // Initialize the IAudioClient.
  169. hr = audio_client_->Initialize(
  170. AUDCLNT_SHAREMODE_SHARED,
  171. AUDCLNT_STREAMFLAGS_LOOPBACK,
  172. (kMaxExpectedTimerLag + audio_device_period_.InMilliseconds()) *
  173. k100nsPerMillisecond,
  174. 0,
  175. wave_format_ex_,
  176. nullptr);
  177. if (FAILED(hr)) {
  178. LOG(ERROR) << "Failed to initialize IAudioClient. Error " << hr;
  179. return false;
  180. }
  181. // Get an IAudioCaptureClient.
  182. hr = audio_client_->GetService(IID_PPV_ARGS(&audio_capture_client_));
  183. if (FAILED(hr)) {
  184. LOG(ERROR) << "Failed to get an IAudioCaptureClient. Error " << hr;
  185. return false;
  186. }
  187. // Start the IAudioClient.
  188. hr = audio_client_->Start();
  189. if (FAILED(hr)) {
  190. LOG(ERROR) << "Failed to start IAudioClient. Error " << hr;
  191. return false;
  192. }
  193. volume_filter_.ActivateBy(mm_device_.Get());
  194. volume_filter_.Initialize(sampling_rate_, wave_format_ex_->nChannels);
  195. return true;
  196. }
  197. bool AudioCapturerWin::is_initialized() const {
  198. // All Com components should be initialized / deinitialized together.
  199. return !!audio_client_;
  200. }
  201. void AudioCapturerWin::DoCapture() {
  202. DCHECK(AudioCapturer::IsValidSampleRate(sampling_rate_));
  203. DCHECK(thread_checker_.CalledOnValidThread());
  204. if (!is_initialized() || default_device_detector_->GetAndReset()) {
  205. if (!ResetAndInitialize()) {
  206. // Initialization failed, we should wait for next DoCapture call.
  207. return;
  208. }
  209. }
  210. // Fetch all packets from the audio capture endpoint buffer.
  211. HRESULT hr = S_OK;
  212. while (true) {
  213. UINT32 next_packet_size;
  214. hr = audio_capture_client_->GetNextPacketSize(&next_packet_size);
  215. if (FAILED(hr))
  216. break;
  217. if (next_packet_size <= 0) {
  218. return;
  219. }
  220. BYTE* data;
  221. UINT32 frames;
  222. DWORD flags;
  223. hr = audio_capture_client_->GetBuffer(&data, &frames, &flags, nullptr,
  224. nullptr);
  225. if (FAILED(hr))
  226. break;
  227. if (volume_filter_.Apply(reinterpret_cast<int16_t*>(data), frames)) {
  228. std::unique_ptr<AudioPacket> packet(new AudioPacket());
  229. packet->add_data(data, frames * wave_format_ex_->nBlockAlign);
  230. packet->set_encoding(AudioPacket::ENCODING_RAW);
  231. packet->set_sampling_rate(sampling_rate_);
  232. packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
  233. // Only the count of channels is taken into account now, we should also
  234. // consider dwChannelMask.
  235. // TODO(zijiehe): Convert dwChannelMask to layout and pass it to
  236. // AudioPump. So the stream can be downmixed properly with both number and
  237. // layouts of speakers.
  238. packet->set_channels(static_cast<AudioPacket::Channels>(
  239. wave_format_ex_->nChannels));
  240. callback_.Run(std::move(packet));
  241. }
  242. hr = audio_capture_client_->ReleaseBuffer(frames);
  243. if (FAILED(hr))
  244. break;
  245. }
  246. // There is nothing to capture if the audio endpoint device has been unplugged
  247. // or disabled.
  248. if (hr == AUDCLNT_E_DEVICE_INVALIDATED)
  249. return;
  250. // Avoid reporting the same error multiple times.
  251. if (FAILED(hr) && hr != last_capture_error_) {
  252. last_capture_error_ = hr;
  253. LOG(ERROR) << "Failed to capture an audio packet: 0x"
  254. << std::hex << hr << std::dec << ".";
  255. }
  256. }
  257. bool AudioCapturer::IsSupported() {
  258. return true;
  259. }
  260. std::unique_ptr<AudioCapturer> AudioCapturer::Create() {
  261. return base::WrapUnique(new AudioCapturerWin());
  262. }
  263. } // namespace remoting