1
1
diff --git a/modules/audio_device/win/audio_device_core_win.cc b/modules/audio_device/win/audio_device_core_win.cc
2
- index f1cc0474fc..ffb0b159b1 100644
2
+ index f1cc0474fc..f8e4f25bb9 100644
3
3
--- a/modules/audio_device/win/audio_device_core_win.cc
4
4
+++ b/modules/audio_device/win/audio_device_core_win.cc
5
- @@ -1846,7 +1846,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
5
+ @@ -1845,8 +1845,8 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
6
+
6
7
HRESULT hr = S_OK;
7
8
WAVEFORMATEX* pWfxOut = NULL;
8
- WAVEFORMATEX Wfx = WAVEFORMATEX();
9
+ - WAVEFORMATEX Wfx = WAVEFORMATEX();
9
10
- WAVEFORMATEX* pWfxClosestMatch = NULL;
10
- + WAVEFORMATEX* pInitWfxClosestMatch = NULL;
11
+ + WAVEFORMATEXTENSIBLE Wfx = WAVEFORMATEXTENSIBLE();
12
+ + WAVEFORMATEXTENSIBLE* pInitWfxClosestMatch = NULL;
11
13
12
14
// Create COM object with IAudioClient interface.
13
15
SAFE_RELEASE(_ptrClientOut);
14
- @@ -1881,7 +1881,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
15
- Wfx.wBitsPerSample = 16;
16
- Wfx.cbSize = 0;
16
+ @@ -1877,11 +1877,14 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
17
+ }
18
+
19
+ // Set wave format
20
+ - Wfx.wFormatTag = WAVE_FORMAT_PCM;
21
+ - Wfx.wBitsPerSample = 16;
22
+ - Wfx.cbSize = 0;
23
+ + Wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
24
+ + Wfx.Format.wBitsPerSample = 16;
25
+ + Wfx.Format.cbSize = 22;
26
+ + Wfx.dwChannelMask = 0;
27
+ + Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
28
+ + Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
17
29
18
30
- const int freqs[] = {48000, 44100, 16000, 96000, 32000, 8000};
19
31
+ const int freqs[] = {48000, 44100, 16000, 96000, 32000, 8000, 192000};
20
32
hr = S_FALSE;
21
33
22
34
// Iterate over frequencies and channels, in order of priority
23
- @@ -1896,6 +1896,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
35
+ @@ -1889,30 +1892,38 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
36
+ for (unsigned int chan = 0; chan < sizeof(_playChannelsPrioList) /
37
+ sizeof(_playChannelsPrioList[0]);
38
+ chan++) {
39
+ - Wfx.nChannels = _playChannelsPrioList[chan];
40
+ - Wfx.nSamplesPerSec = freqs[freq];
41
+ - Wfx.nBlockAlign = Wfx.nChannels * Wfx.wBitsPerSample / 8;
42
+ - Wfx.nAvgBytesPerSec = Wfx.nSamplesPerSec * Wfx.nBlockAlign;
43
+ + Wfx.Format.nChannels = _playChannelsPrioList[chan];
44
+ + Wfx.Format.nSamplesPerSec = freqs[freq];
45
+ + Wfx.Format.nBlockAlign =
46
+ + Wfx.Format.nChannels * Wfx.Format.wBitsPerSample / 8;
47
+ + Wfx.Format.nAvgBytesPerSec =
48
+ + Wfx.Format.nSamplesPerSec * Wfx.Format.nBlockAlign;
24
49
// If the method succeeds and the audio endpoint device supports the
25
50
// specified stream format, it returns S_OK. If the method succeeds and
26
51
// 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);
52
+ - hr = _ptrClientOut->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &Wfx,
53
+ - &pWfxClosestMatch);
54
+ + WAVEFORMATEXTENSIBLE* pWfxClosestMatch = NULL;
55
+ + hr = _ptrClientOut->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,
56
+ + (WAVEFORMATEX*)&Wfx,
57
+ + (WAVEFORMATEX**)&pWfxClosestMatch);
30
58
if (hr == S_OK) {
31
- @@ -1908,8 +1909,12 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
59
+ break;
60
+ } else {
61
+ if (pWfxClosestMatch) {
62
+ - RTC_LOG(LS_INFO) << "nChannels=" << Wfx.nChannels
63
+ - << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
64
+ + RTC_LOG(LS_INFO) << "nChannels=" << Wfx.Format.nChannels
65
+ + << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
66
+ << " is not supported. Closest match: "
32
67
"nChannels="
33
- << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
34
- << pWfxClosestMatch->nSamplesPerSec;
68
+ - << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
69
+ - << pWfxClosestMatch->nSamplesPerSec;
35
70
- CoTaskMemFree(pWfxClosestMatch);
36
71
- pWfxClosestMatch = NULL;
72
+ + << pWfxClosestMatch->Format.nChannels << ", nSamplesPerSec="
73
+ + << pWfxClosestMatch->Format.nSamplesPerSec;
37
74
+
38
75
+ if (pInitWfxClosestMatch) {
39
76
+ CoTaskMemFree(pWfxClosestMatch);
40
77
+ } else {
41
78
+ pInitWfxClosestMatch = pWfxClosestMatch;
42
79
+ }
43
80
} else {
44
- RTC_LOG(LS_INFO) << "nChannels=" << Wfx.nChannels
45
- << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
46
- @@ -1924,6 +1929,18 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
81
+ - RTC_LOG(LS_INFO) << "nChannels=" << Wfx.nChannels
82
+ - << ", nSamplesPerSec=" << Wfx.nSamplesPerSec
83
+ + RTC_LOG(LS_INFO) << "nChannels=" << Wfx.Format.nChannels
84
+ + << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
85
+ << " is not supported. No closest match.";
86
+ }
87
+ }
88
+ @@ -1924,26 +1935,42 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
47
89
// TODO(andrew): what happens in the event of failure in the above loop?
48
90
// Is _ptrClientOut->Initialize expected to fail?
49
91
// Same in InitRecording().
50
92
+
51
93
+ if (pInitWfxClosestMatch) {
52
94
+ // 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;
95
+ + CopyMemory(&Wfx, pInitWfxClosestMatch, sizeof(Wfx));
96
+ + Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
97
+ + Wfx.Format.wBitsPerSample = 16; // force it to 16 bits per sample
98
+ + Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
99
+ + Wfx.Format.nChannels = 2;
100
+ + Wfx.Format.nBlockAlign =
101
+ + Wfx.Format.nChannels * Wfx.Format.wBitsPerSample / 8;
102
+ + Wfx.Format.nAvgBytesPerSec =
103
+ + Wfx.Format.nSamplesPerSec * Wfx.Format.nBlockAlign;
60
104
+ hr = S_OK;
61
105
+ }
62
106
if (hr == S_OK) {
63
- _playAudioFrameSize = Wfx.nBlockAlign;
107
+ - _playAudioFrameSize = Wfx.nBlockAlign;
108
+ + _playAudioFrameSize = Wfx.Format.nBlockAlign;
64
109
// Block size is the number of samples each channel in 10ms.
65
- @@ -2031,7 +2048,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
110
+ - _playBlockSize = Wfx.nSamplesPerSec / 100;
111
+ - _playSampleRate = Wfx.nSamplesPerSec;
112
+ + _playBlockSize = Wfx.Format.nSamplesPerSec / 100;
113
+ + _playSampleRate = Wfx.Format.nSamplesPerSec;
114
+ _devicePlaySampleRate =
115
+ - Wfx.nSamplesPerSec; // The device itself continues to run at 44.1 kHz.
116
+ - _devicePlayBlockSize = Wfx.nSamplesPerSec / 100;
117
+ - _playChannels = Wfx.nChannels;
118
+ + Wfx.Format
119
+ + .nSamplesPerSec; // The device itself continues to run at 44.1 kHz.
120
+ + _devicePlayBlockSize = Wfx.Format.nSamplesPerSec / 100;
121
+ + _playChannels = Wfx.Format.nChannels;
122
+
123
+ RTC_LOG(LS_VERBOSE) << "VoE selected this rendering format:";
124
+ RTC_LOG(LS_VERBOSE) << "wFormatTag : 0x"
125
+ - << webrtc::ToHex(Wfx.wFormatTag) << " ("
126
+ - << Wfx.wFormatTag << ")";
127
+ - RTC_LOG(LS_VERBOSE) << "nChannels : " << Wfx.nChannels;
128
+ - RTC_LOG(LS_VERBOSE) << "nSamplesPerSec : " << Wfx.nSamplesPerSec;
129
+ - RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec : " << Wfx.nAvgBytesPerSec;
130
+ - RTC_LOG(LS_VERBOSE) << "nBlockAlign : " << Wfx.nBlockAlign;
131
+ - RTC_LOG(LS_VERBOSE) << "wBitsPerSample : " << Wfx.wBitsPerSample;
132
+ - RTC_LOG(LS_VERBOSE) << "cbSize : " << Wfx.cbSize;
133
+ + << webrtc::ToHex(Wfx.Format.wFormatTag) << " ("
134
+ + << Wfx.Format.wFormatTag << ")";
135
+ + RTC_LOG(LS_VERBOSE) << "nChannels : " << Wfx.Format.nChannels;
136
+ + RTC_LOG(LS_VERBOSE) << "nSamplesPerSec : " << Wfx.Format.nSamplesPerSec;
137
+ + RTC_LOG(LS_VERBOSE) << "nAvgBytesPerSec : "
138
+ + << Wfx.Format.nAvgBytesPerSec;
139
+ + RTC_LOG(LS_VERBOSE) << "nBlockAlign : " << Wfx.Format.nBlockAlign;
140
+ + RTC_LOG(LS_VERBOSE) << "wBitsPerSample : " << Wfx.Format.wBitsPerSample;
141
+ + RTC_LOG(LS_VERBOSE) << "cbSize : " << Wfx.Format.cbSize;
142
+ RTC_LOG(LS_VERBOSE) << "Additional settings:";
143
+ RTC_LOG(LS_VERBOSE) << "_playAudioFrameSize: " << _playAudioFrameSize;
144
+ RTC_LOG(LS_VERBOSE) << "_playBlockSize : " << _playBlockSize;
145
+ @@ -1980,12 +2007,14 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
146
+ }
147
+ hr = _ptrClientOut->Initialize(
148
+ AUDCLNT_SHAREMODE_SHARED, // share Audio Engine with other applications
149
+ - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, // processing of the audio buffer by
150
+ + AUDCLNT_STREAMFLAGS_EVENTCALLBACK | // processing of the audio buffer by
151
+ // the client will be event driven
152
+ + AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM |
153
+ + AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY,
154
+ hnsBufferDuration, // requested buffer capacity as a time value (in
155
+ // 100-nanosecond units)
156
+ 0, // periodicity
157
+ - &Wfx, // selected wave format
158
+ + (WAVEFORMATEX *)&Wfx, // selected wave format
159
+ NULL); // session GUID
160
+
161
+ if (FAILED(hr)) {
162
+ @@ -2031,7 +2060,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
66
163
_playIsInitialized = true;
67
164
68
165
CoTaskMemFree(pWfxOut);
@@ -71,7 +168,7 @@ index f1cc0474fc..ffb0b159b1 100644
71
168
72
169
RTC_LOG(LS_VERBOSE) << "render side is now initialized";
73
170
return 0;
74
- @@ -2039,7 +2056 ,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
171
+ @@ -2039,7 +2068 ,7 @@ int32_t AudioDeviceWindowsCore::InitPlayout() {
75
172
Exit:
76
173
_TraceCOMError(hr);
77
174
CoTaskMemFree(pWfxOut);
@@ -80,16 +177,16 @@ index f1cc0474fc..ffb0b159b1 100644
80
177
SAFE_RELEASE(_ptrClientOut);
81
178
SAFE_RELEASE(_ptrRenderClient);
82
179
return -1;
83
- @@ -2163,7 +2180 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
180
+ @@ -2163,7 +2192 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
84
181
HRESULT hr = S_OK;
85
182
WAVEFORMATEX* pWfxIn = NULL;
86
183
WAVEFORMATEXTENSIBLE Wfx = WAVEFORMATEXTENSIBLE();
87
184
- WAVEFORMATEX* pWfxClosestMatch = NULL;
88
- + WAVEFORMATEX * pInitWfxClosestMatch = NULL;
185
+ + WAVEFORMATEXTENSIBLE * pInitWfxClosestMatch = NULL;
89
186
90
187
// Create COM object with IAudioClient interface.
91
188
SAFE_RELEASE(_ptrClientIn);
92
- @@ -2201,7 +2218 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
189
+ @@ -2201,7 +2230 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
93
190
Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
94
191
Wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
95
192
@@ -98,20 +195,30 @@ index f1cc0474fc..ffb0b159b1 100644
98
195
hr = S_FALSE;
99
196
100
197
// Iterate over frequencies and channels, in order of priority
101
- @@ -2218,6 +2235,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
198
+ @@ -2218,8 +2247,10 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
102
199
// If the method succeeds and the audio endpoint device supports the
103
200
// specified stream format, it returns S_OK. If the method succeeds and
104
201
// 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);
202
+ - hr = _ptrClientIn->IsFormatSupported(
203
+ - AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*)&Wfx, &pWfxClosestMatch);
204
+ + WAVEFORMATEXTENSIBLE* pWfxClosestMatch = NULL;
205
+ + hr = _ptrClientIn->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,
206
+ + (WAVEFORMATEX*)&Wfx,
207
+ + (WAVEFORMATEX**)&pWfxClosestMatch);
108
208
if (hr == S_OK) {
109
- @@ -2230,8 +2248,11 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
209
+ break;
210
+ } else {
211
+ @@ -2228,10 +2259,14 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
212
+ << ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
213
+ << " is not supported. Closest match: "
110
214
"nChannels="
111
- << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
112
- << pWfxClosestMatch->nSamplesPerSec;
215
+ - << pWfxClosestMatch->nChannels << ", nSamplesPerSec="
216
+ - << pWfxClosestMatch->nSamplesPerSec;
113
217
- CoTaskMemFree(pWfxClosestMatch);
114
218
- pWfxClosestMatch = NULL;
219
+ + << pWfxClosestMatch->Format.nChannels
220
+ + << ", nSamplesPerSec="
221
+ + << pWfxClosestMatch->Format.nSamplesPerSec;
115
222
+ if (pInitWfxClosestMatch) {
116
223
+ CoTaskMemFree(pWfxClosestMatch);
117
224
+ } else {
@@ -120,31 +227,38 @@ index f1cc0474fc..ffb0b159b1 100644
120
227
} else {
121
228
RTC_LOG(LS_INFO) << "nChannels=" << Wfx.Format.nChannels
122
229
<< ", nSamplesPerSec=" << Wfx.Format.nSamplesPerSec
123
- @@ -2242,7 +2263,22 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
230
+ @@ -2242,7 +2277,20 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
124
231
if (hr == S_OK)
125
232
break;
126
233
}
127
234
-
128
235
+ if (pInitWfxClosestMatch) {
129
236
+ // Set up the closest match, and rely on the voice engine to resample.
130
237
+ // (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;
238
+ + CopyMemory(&Wfx, pInitWfxClosestMatch, sizeof(Wfx));
136
239
+ 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;
240
+ + Wfx.Format.wBitsPerSample = 16; // force it to 16 bits per sample
241
+ + Wfx.Samples.wValidBitsPerSample = Wfx.Format.wBitsPerSample;
242
+ + Wfx.Format.nChannels = 1;
243
+ + Wfx.Format.nBlockAlign =
244
+ + Wfx.Format.nChannels * Wfx.Format.wBitsPerSample / 8;
245
+ + Wfx.Format.nAvgBytesPerSec =
246
+ + Wfx.Format.nSamplesPerSec * Wfx.Format.nBlockAlign;
142
247
+ hr = S_OK;
143
248
+ }
144
249
if (hr == S_OK) {
145
250
_recAudioFrameSize = Wfx.Format.nBlockAlign;
146
251
_recSampleRate = Wfx.Format.nSamplesPerSec;
147
- @@ -2321,7 +2357,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
252
+ @@ -2270,6 +2318,8 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
253
+ AUDCLNT_SHAREMODE_SHARED, // share Audio Engine with other applications
254
+ AUDCLNT_STREAMFLAGS_EVENTCALLBACK | // processing of the audio buffer by
255
+ // the client will be event driven
256
+ + AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM |
257
+ + AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY |
258
+ AUDCLNT_STREAMFLAGS_NOPERSIST, // volume and mute settings for an
259
+ // audio session will not persist
260
+ // across system restarts
261
+ @@ -2321,7 +2371,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
148
262
_recIsInitialized = true;
149
263
150
264
CoTaskMemFree(pWfxIn);
@@ -153,7 +267,7 @@ index f1cc0474fc..ffb0b159b1 100644
153
267
154
268
RTC_LOG(LS_VERBOSE) << "capture side is now initialized";
155
269
return 0;
156
- @@ -2329,7 +2365 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
270
+ @@ -2329,7 +2379 ,7 @@ int32_t AudioDeviceWindowsCore::InitRecording() {
157
271
Exit:
158
272
_TraceCOMError(hr);
159
273
CoTaskMemFree(pWfxIn);
0 commit comments