11diff --git a/modules/audio_device/win/audio_device_core_win.cc b/modules/audio_device/win/audio_device_core_win.cc
2- index f1cc0474fc..34eeaacc39 100644
2+ index f1cc0474fc..ffb0b159b1 100644
33--- a/modules/audio_device/win/audio_device_core_win.cc
44+++ b/modules/audio_device/win/audio_device_core_win.cc
5+ @@ -1846,7 +1846,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
6+ HRESULT hr = S_OK;
7+ WAVEFORMATEX* pWfxOut = NULL;
8+ WAVEFORMATEX Wfx = WAVEFORMATEX();
9+ - WAVEFORMATEX* pWfxClosestMatch = NULL;
10+ + WAVEFORMATEX* pInitWfxClosestMatch = NULL;
11+
12+ // Create COM object with IAudioClient interface.
13+ SAFE_RELEASE(_ptrClientOut);
514@@ -1881,7 +1881,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
615 Wfx.wBitsPerSample = 16;
716 Wfx.cbSize = 0;
@@ -11,7 +20,76 @@ index f1cc0474fc..34eeaacc39 100644
1120 hr = S_FALSE;
1221
1322 // Iterate over frequencies and channels, in order of priority
14- @@ -2201,7 +2201,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
23+ @@ -1896,6 +1896,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
24+ // If the method succeeds and the audio endpoint device supports the
25+ // specified stream format, it returns S_OK. If the method succeeds and
26+ // provides a closest match to the specified format, it returns S_FALSE.
27+ + WAVEFORMATEX* pWfxClosestMatch = NULL;
28+ hr = _ptrClientOut->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &Wfx,
29+ &pWfxClosestMatch);
30+ if (hr == S_OK) {
31+ @@ -1908,8 +1909,12 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
32+ "nChannels="
33+ << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
34+ << pWfxClosestMatch->nSamplesPerSec;
35+ - CoTaskMemFree(pWfxClosestMatch);
36+ - pWfxClosestMatch = NULL;
37+ +
38+ + if (pInitWfxClosestMatch) {
39+ + CoTaskMemFree(pWfxClosestMatch);
40+ + } else {
41+ + pInitWfxClosestMatch = pWfxClosestMatch;
42+ + }
43+ } else {
44+ RTC_LOG(LS_INFO) << "nChannels=" << Wfx.nChannels
45+ << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
46+ @@ -1924,6 +1929,18 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
47+ // TODO(andrew): what happens in the event of failure in the above loop?
48+ // Is _ptrClientOut->Initialize expected to fail?
49+ // Same in InitRecording().
50+ +
51+ + if (pInitWfxClosestMatch) {
52+ + // Set up the closest match, and rely on the voice engine to resample. (roxanneskelly)
53+ + Wfx.wFormatTag = WAVE_FORMAT_PCM;
54+ + Wfx.wBitsPerSample = 16;
55+ + Wfx.cbSize = 0;
56+ + Wfx.nChannels = pInitWfxClosestMatch->nChannels;
57+ + Wfx.nSamplesPerSec = pInitWfxClosestMatch->nSamplesPerSec;
58+ + Wfx.nBlockAlign = pInitWfxClosestMatch->nBlockAlign;
59+ + Wfx.nAvgBytesPerSec = pInitWfxClosestMatch->nAvgBytesPerSec;
60+ + hr = S_OK;
61+ + }
62+ if (hr == S_OK) {
63+ _playAudioFrameSize = Wfx.nBlockAlign;
64+ // Block size is the number of samples each channel in 10ms.
65+ @@ -2031,7 +2048,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
66+ _playIsInitialized = true;
67+
68+ CoTaskMemFree(pWfxOut);
69+ - CoTaskMemFree(pWfxClosestMatch);
70+ + CoTaskMemFree(pInitWfxClosestMatch);
71+
72+ RTC_LOG(LS_VERBOSE) << "render side is now initialized";
73+ return 0;
74+ @@ -2039,7 +2056,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
75+ Exit:
76+ _TraceCOMError(hr);
77+ CoTaskMemFree(pWfxOut);
78+ - CoTaskMemFree(pWfxClosestMatch);
79+ + CoTaskMemFree(pInitWfxClosestMatch);
80+ SAFE_RELEASE(_ptrClientOut);
81+ SAFE_RELEASE(_ptrRenderClient);
82+ return -1;
83+ @@ -2163,7 +2180,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
84+ HRESULT hr = S_OK;
85+ WAVEFORMATEX* pWfxIn = NULL;
86+ WAVEFORMATEXTENSIBLE Wfx = WAVEFORMATEXTENSIBLE();
87+ - WAVEFORMATEX* pWfxClosestMatch = NULL;
88+ + WAVEFORMATEX* pInitWfxClosestMatch = NULL;
89+
90+ // Create COM object with IAudioClient interface.
91+ SAFE_RELEASE(_ptrClientIn);
92+ @@ -2201,7 +2218,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
1593 Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
1694 Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
1795
@@ -20,3 +98,67 @@ index f1cc0474fc..34eeaacc39 100644
2098 hr = S_FALSE;
2199
22100 // Iterate over frequencies and channels, in order of priority
101+ @@ -2218,6 +2235,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
102+ // If the method succeeds and the audio endpoint device supports the
103+ // specified stream format, it returns S_OK. If the method succeeds and
104+ // provides a closest match to the specified format, it returns S_FALSE.
105+ + WAVEFORMATEX* pWfxClosestMatch = NULL;
106+ hr = _ptrClientIn->IsFormatSupported(
107+ AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*)&Wfx, &pWfxClosestMatch);
108+ if (hr == S_OK) {
109+ @@ -2230,8 +2248,11 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
110+ "nChannels="
111+ << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
112+ << pWfxClosestMatch->nSamplesPerSec;
113+ - CoTaskMemFree(pWfxClosestMatch);
114+ - pWfxClosestMatch = NULL;
115+ + if (pInitWfxClosestMatch) {
116+ + CoTaskMemFree(pWfxClosestMatch);
117+ + } else {
118+ + pInitWfxClosestMatch = pWfxClosestMatch;
119+ + }
120+ } else {
121+ RTC_LOG(LS_INFO) << "nChannels=" << Wfx.Format.nChannels
122+ << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
123+ @@ -2242,7 +2263,22 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
124+ if (hr == S_OK)
125+ break;
126+ }
127+ -
128+ + if (pInitWfxClosestMatch) {
129+ + // Set up the closest match, and rely on the voice engine to resample.
130+ + // (roxanneskelly)
131+ + Wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
132+ + Wfx.Format.wBitsPerSample = 16;
133+ + Wfx.Format.cbSize = 22;
134+ + Wfx.dwChannelMask = 0;
135+ + Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
136+ + Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
137+ +
138+ + Wfx.Format.nChannels = pInitWfxClosestMatch->nChannels;
139+ + Wfx.Format.nSamplesPerSec = pInitWfxClosestMatch->nSamplesPerSec;
140+ + Wfx.Format.nBlockAlign = pInitWfxClosestMatch->nBlockAlign;
141+ + Wfx.Format.nAvgBytesPerSec = pInitWfxClosestMatch->nAvgBytesPerSec;
142+ + hr = S_OK;
143+ + }
144+ if (hr == S_OK) {
145+ _recAudioFrameSize = Wfx.Format.nBlockAlign;
146+ _recSampleRate = Wfx.Format.nSamplesPerSec;
147+ @@ -2321,7 +2357,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
148+ _recIsInitialized = true;
149+
150+ CoTaskMemFree(pWfxIn);
151+ - CoTaskMemFree(pWfxClosestMatch);
152+ + CoTaskMemFree(pInitWfxClosestMatch);
153+
154+ RTC_LOG(LS_VERBOSE) << "capture side is now initialized";
155+ return 0;
156+ @@ -2329,7 +2365,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
157+ Exit:
158+ _TraceCOMError(hr);
159+ CoTaskMemFree(pWfxIn);
160+ - CoTaskMemFree(pWfxClosestMatch);
161+ + CoTaskMemFree(pInitWfxClosestMatch);
162+ SAFE_RELEASE(_ptrClientIn);
163+ SAFE_RELEASE(_ptrCaptureClient);
164+ return -1;
0 commit comments