OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "base/strings/utf_string_conversions.h" | 6 #include "base/strings/utf_string_conversions.h" |
7 #include "base/synchronization/waitable_event.h" | 7 #include "base/synchronization/waitable_event.h" |
8 #include "base/win/scoped_co_mem.h" | 8 #include "base/win/scoped_co_mem.h" |
9 #include "base/win/scoped_com_initializer.h" | 9 #include "base/win/scoped_com_initializer.h" |
10 #include "base/win/scoped_handle.h" | 10 #include "base/win/scoped_handle.h" |
| 11 #include "media/audio/audio_unittest_util.h" |
11 #include "media/audio/win/core_audio_util_win.h" | 12 #include "media/audio/win/core_audio_util_win.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
14 | 15 |
15 using base::win::ScopedCOMInitializer; | 16 using base::win::ScopedCOMInitializer; |
16 | 17 |
17 namespace media { | 18 namespace media { |
18 | 19 |
19 class CoreAudioUtilWinTest : public ::testing::Test { | 20 class CoreAudioUtilWinTest : public ::testing::Test { |
20 protected: | 21 protected: |
21 // The test runs on a COM thread in the multithreaded apartment (MTA). | 22 // The test runs on a COM thread in the multithreaded apartment (MTA). |
22 // If we don't initialize the COM library on a thread before using COM, | 23 // If we don't initialize the COM library on a thread before using COM, |
23 // all function calls will return CO_E_NOTINITIALIZED. | 24 // all function calls will return CO_E_NOTINITIALIZED. |
24 CoreAudioUtilWinTest() | 25 CoreAudioUtilWinTest() |
25 : com_init_(ScopedCOMInitializer::kMTA) { | 26 : com_init_(ScopedCOMInitializer::kMTA) { |
26 DCHECK(com_init_.succeeded()); | 27 DCHECK(com_init_.succeeded()); |
27 } | 28 } |
28 virtual ~CoreAudioUtilWinTest() {} | 29 virtual ~CoreAudioUtilWinTest() {} |
29 | 30 |
30 bool CanRunAudioTest() { | 31 bool DevicesAvailable() { |
31 bool core_audio = CoreAudioUtil::IsSupported(); | 32 if (!CoreAudioUtil::IsSupported()) |
32 if (!core_audio) | |
33 return false; | 33 return false; |
34 int capture_devices = CoreAudioUtil::NumberOfActiveDevices(eCapture); | 34 return CoreAudioUtil::NumberOfActiveDevices(eCapture) > 0 && |
35 int render_devices = CoreAudioUtil::NumberOfActiveDevices(eRender); | 35 CoreAudioUtil::NumberOfActiveDevices(eRender) > 0; |
36 return ((capture_devices > 0) && (render_devices > 0)); | |
37 } | 36 } |
38 | 37 |
39 ScopedCOMInitializer com_init_; | 38 ScopedCOMInitializer com_init_; |
40 }; | 39 }; |
41 | 40 |
42 TEST_F(CoreAudioUtilWinTest, NumberOfActiveDevices) { | 41 TEST_F(CoreAudioUtilWinTest, NumberOfActiveDevices) { |
43 if (!CanRunAudioTest()) | 42 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
44 return; | |
45 | 43 |
46 int render_devices = CoreAudioUtil::NumberOfActiveDevices(eRender); | 44 int render_devices = CoreAudioUtil::NumberOfActiveDevices(eRender); |
47 EXPECT_GT(render_devices, 0); | 45 EXPECT_GT(render_devices, 0); |
48 int capture_devices = CoreAudioUtil::NumberOfActiveDevices(eCapture); | 46 int capture_devices = CoreAudioUtil::NumberOfActiveDevices(eCapture); |
49 EXPECT_GT(capture_devices, 0); | 47 EXPECT_GT(capture_devices, 0); |
50 int total_devices = CoreAudioUtil::NumberOfActiveDevices(eAll); | 48 int total_devices = CoreAudioUtil::NumberOfActiveDevices(eAll); |
51 EXPECT_EQ(total_devices, render_devices + capture_devices); | 49 EXPECT_EQ(total_devices, render_devices + capture_devices); |
52 } | 50 } |
53 | 51 |
54 TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) { | 52 TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) { |
55 if (!CanRunAudioTest()) | 53 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
56 return; | |
57 | 54 |
58 ScopedComPtr<IMMDeviceEnumerator> enumerator = | 55 ScopedComPtr<IMMDeviceEnumerator> enumerator = |
59 CoreAudioUtil::CreateDeviceEnumerator(); | 56 CoreAudioUtil::CreateDeviceEnumerator(); |
60 EXPECT_TRUE(enumerator.get()); | 57 EXPECT_TRUE(enumerator.get()); |
61 } | 58 } |
62 | 59 |
63 TEST_F(CoreAudioUtilWinTest, CreateDefaultDevice) { | 60 TEST_F(CoreAudioUtilWinTest, CreateDefaultDevice) { |
64 if (!CanRunAudioTest()) | 61 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
65 return; | |
66 | 62 |
67 struct { | 63 struct { |
68 EDataFlow flow; | 64 EDataFlow flow; |
69 ERole role; | 65 ERole role; |
70 } data[] = { | 66 } data[] = { |
71 {eRender, eConsole}, | 67 {eRender, eConsole}, |
72 {eRender, eCommunications}, | 68 {eRender, eCommunications}, |
73 {eRender, eMultimedia}, | 69 {eRender, eMultimedia}, |
74 {eCapture, eConsole}, | 70 {eCapture, eConsole}, |
75 {eCapture, eCommunications}, | 71 {eCapture, eCommunications}, |
76 {eCapture, eMultimedia} | 72 {eCapture, eMultimedia} |
77 }; | 73 }; |
78 | 74 |
79 // Create default devices for all flow/role combinations above. | 75 // Create default devices for all flow/role combinations above. |
80 ScopedComPtr<IMMDevice> audio_device; | 76 ScopedComPtr<IMMDevice> audio_device; |
81 for (int i = 0; i < arraysize(data); ++i) { | 77 for (int i = 0; i < arraysize(data); ++i) { |
82 audio_device = | 78 audio_device = |
83 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); | 79 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); |
84 EXPECT_TRUE(audio_device.get()); | 80 EXPECT_TRUE(audio_device.get()); |
85 EXPECT_EQ(data[i].flow, CoreAudioUtil::GetDataFlow(audio_device.get())); | 81 EXPECT_EQ(data[i].flow, CoreAudioUtil::GetDataFlow(audio_device.get())); |
86 } | 82 } |
87 | 83 |
88 // Only eRender and eCapture are allowed as flow parameter. | 84 // Only eRender and eCapture are allowed as flow parameter. |
89 audio_device = CoreAudioUtil::CreateDefaultDevice(eAll, eConsole); | 85 audio_device = CoreAudioUtil::CreateDefaultDevice(eAll, eConsole); |
90 EXPECT_FALSE(audio_device.get()); | 86 EXPECT_FALSE(audio_device.get()); |
91 } | 87 } |
92 | 88 |
93 TEST_F(CoreAudioUtilWinTest, CreateDevice) { | 89 TEST_F(CoreAudioUtilWinTest, CreateDevice) { |
94 if (!CanRunAudioTest()) | 90 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
95 return; | |
96 | 91 |
97 // Get name and ID of default device used for playback. | 92 // Get name and ID of default device used for playback. |
98 ScopedComPtr<IMMDevice> default_render_device = | 93 ScopedComPtr<IMMDevice> default_render_device = |
99 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 94 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
100 AudioDeviceName default_render_name; | 95 AudioDeviceName default_render_name; |
101 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName( | 96 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName( |
102 default_render_device.get(), &default_render_name))); | 97 default_render_device.get(), &default_render_name))); |
103 | 98 |
104 // Use the uniqe ID as input to CreateDevice() and create a corresponding | 99 // Use the uniqe ID as input to CreateDevice() and create a corresponding |
105 // IMMDevice. | 100 // IMMDevice. |
106 ScopedComPtr<IMMDevice> audio_device = | 101 ScopedComPtr<IMMDevice> audio_device = |
107 CoreAudioUtil::CreateDevice(default_render_name.unique_id); | 102 CoreAudioUtil::CreateDevice(default_render_name.unique_id); |
108 EXPECT_TRUE(audio_device.get()); | 103 EXPECT_TRUE(audio_device.get()); |
109 | 104 |
110 // Verify that the two IMMDevice interfaces represents the same endpoint | 105 // Verify that the two IMMDevice interfaces represents the same endpoint |
111 // by comparing their unique IDs. | 106 // by comparing their unique IDs. |
112 AudioDeviceName device_name; | 107 AudioDeviceName device_name; |
113 EXPECT_TRUE(SUCCEEDED( | 108 EXPECT_TRUE(SUCCEEDED( |
114 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); | 109 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); |
115 EXPECT_EQ(default_render_name.unique_id, device_name.unique_id); | 110 EXPECT_EQ(default_render_name.unique_id, device_name.unique_id); |
116 } | 111 } |
117 | 112 |
118 TEST_F(CoreAudioUtilWinTest, GetDefaultDeviceName) { | 113 TEST_F(CoreAudioUtilWinTest, GetDefaultDeviceName) { |
119 if (!CanRunAudioTest()) | 114 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
120 return; | |
121 | 115 |
122 struct { | 116 struct { |
123 EDataFlow flow; | 117 EDataFlow flow; |
124 ERole role; | 118 ERole role; |
125 } data[] = { | 119 } data[] = { |
126 {eRender, eConsole}, | 120 {eRender, eConsole}, |
127 {eRender, eCommunications}, | 121 {eRender, eCommunications}, |
128 {eCapture, eConsole}, | 122 {eCapture, eConsole}, |
129 {eCapture, eCommunications} | 123 {eCapture, eCommunications} |
130 }; | 124 }; |
131 | 125 |
132 // Get name and ID of default devices for all flow/role combinations above. | 126 // Get name and ID of default devices for all flow/role combinations above. |
133 ScopedComPtr<IMMDevice> audio_device; | 127 ScopedComPtr<IMMDevice> audio_device; |
134 AudioDeviceName device_name; | 128 AudioDeviceName device_name; |
135 for (int i = 0; i < arraysize(data); ++i) { | 129 for (int i = 0; i < arraysize(data); ++i) { |
136 audio_device = | 130 audio_device = |
137 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); | 131 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); |
138 EXPECT_TRUE(SUCCEEDED( | 132 EXPECT_TRUE(SUCCEEDED( |
139 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); | 133 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); |
140 EXPECT_FALSE(device_name.device_name.empty()); | 134 EXPECT_FALSE(device_name.device_name.empty()); |
141 EXPECT_FALSE(device_name.unique_id.empty()); | 135 EXPECT_FALSE(device_name.unique_id.empty()); |
142 } | 136 } |
143 } | 137 } |
144 | 138 |
145 TEST_F(CoreAudioUtilWinTest, GetAudioControllerID) { | 139 TEST_F(CoreAudioUtilWinTest, GetAudioControllerID) { |
146 if (!CanRunAudioTest()) | 140 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
147 return; | |
148 | 141 |
149 ScopedComPtr<IMMDeviceEnumerator> enumerator( | 142 ScopedComPtr<IMMDeviceEnumerator> enumerator( |
150 CoreAudioUtil::CreateDeviceEnumerator()); | 143 CoreAudioUtil::CreateDeviceEnumerator()); |
151 ASSERT_TRUE(enumerator.get()); | 144 ASSERT_TRUE(enumerator.get()); |
152 | 145 |
153 // Enumerate all active input and output devices and fetch the ID of | 146 // Enumerate all active input and output devices and fetch the ID of |
154 // the associated device. | 147 // the associated device. |
155 EDataFlow flows[] = { eRender , eCapture }; | 148 EDataFlow flows[] = { eRender , eCapture }; |
156 for (int i = 0; i < arraysize(flows); ++i) { | 149 for (int i = 0; i < arraysize(flows); ++i) { |
157 ScopedComPtr<IMMDeviceCollection> collection; | 150 ScopedComPtr<IMMDeviceCollection> collection; |
158 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(flows[i], | 151 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(flows[i], |
159 DEVICE_STATE_ACTIVE, collection.Receive()))); | 152 DEVICE_STATE_ACTIVE, collection.Receive()))); |
160 UINT count = 0; | 153 UINT count = 0; |
161 collection->GetCount(&count); | 154 collection->GetCount(&count); |
162 for (UINT j = 0; j < count; ++j) { | 155 for (UINT j = 0; j < count; ++j) { |
163 ScopedComPtr<IMMDevice> device; | 156 ScopedComPtr<IMMDevice> device; |
164 collection->Item(j, device.Receive()); | 157 collection->Item(j, device.Receive()); |
165 std::string controller_id( | 158 std::string controller_id( |
166 CoreAudioUtil::GetAudioControllerID(device.get(), enumerator.get())); | 159 CoreAudioUtil::GetAudioControllerID(device.get(), enumerator.get())); |
167 EXPECT_FALSE(controller_id.empty()); | 160 EXPECT_FALSE(controller_id.empty()); |
168 } | 161 } |
169 } | 162 } |
170 } | 163 } |
171 | 164 |
172 TEST_F(CoreAudioUtilWinTest, GetFriendlyName) { | 165 TEST_F(CoreAudioUtilWinTest, GetFriendlyName) { |
173 if (!CanRunAudioTest()) | 166 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
174 return; | |
175 | 167 |
176 // Get name and ID of default device used for recording. | 168 // Get name and ID of default device used for recording. |
177 ScopedComPtr<IMMDevice> audio_device = | 169 ScopedComPtr<IMMDevice> audio_device = |
178 CoreAudioUtil::CreateDefaultDevice(eCapture, eConsole); | 170 CoreAudioUtil::CreateDefaultDevice(eCapture, eConsole); |
179 AudioDeviceName device_name; | 171 AudioDeviceName device_name; |
180 HRESULT hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); | 172 HRESULT hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); |
181 EXPECT_TRUE(SUCCEEDED(hr)); | 173 EXPECT_TRUE(SUCCEEDED(hr)); |
182 | 174 |
183 // Use unique ID as input to GetFriendlyName() and compare the result | 175 // Use unique ID as input to GetFriendlyName() and compare the result |
184 // with the already obtained friendly name for the default capture device. | 176 // with the already obtained friendly name for the default capture device. |
185 std::string friendly_name = CoreAudioUtil::GetFriendlyName( | 177 std::string friendly_name = CoreAudioUtil::GetFriendlyName( |
186 device_name.unique_id); | 178 device_name.unique_id); |
187 EXPECT_EQ(friendly_name, device_name.device_name); | 179 EXPECT_EQ(friendly_name, device_name.device_name); |
188 | 180 |
189 // Same test as above but for playback. | 181 // Same test as above but for playback. |
190 audio_device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 182 audio_device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
191 hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); | 183 hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); |
192 EXPECT_TRUE(SUCCEEDED(hr)); | 184 EXPECT_TRUE(SUCCEEDED(hr)); |
193 friendly_name = CoreAudioUtil::GetFriendlyName(device_name.unique_id); | 185 friendly_name = CoreAudioUtil::GetFriendlyName(device_name.unique_id); |
194 EXPECT_EQ(friendly_name, device_name.device_name); | 186 EXPECT_EQ(friendly_name, device_name.device_name); |
195 } | 187 } |
196 | 188 |
197 TEST_F(CoreAudioUtilWinTest, DeviceIsDefault) { | 189 TEST_F(CoreAudioUtilWinTest, DeviceIsDefault) { |
198 if (!CanRunAudioTest()) | 190 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
199 return; | |
200 | 191 |
201 // Verify that the default render device is correctly identified as a | 192 // Verify that the default render device is correctly identified as a |
202 // default device. | 193 // default device. |
203 ScopedComPtr<IMMDevice> audio_device = | 194 ScopedComPtr<IMMDevice> audio_device = |
204 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 195 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
205 AudioDeviceName name; | 196 AudioDeviceName name; |
206 EXPECT_TRUE( | 197 EXPECT_TRUE( |
207 SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device.get(), &name))); | 198 SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device.get(), &name))); |
208 const std::string id = name.unique_id; | 199 const std::string id = name.unique_id; |
209 EXPECT_TRUE(CoreAudioUtil::DeviceIsDefault(eRender, eConsole, id)); | 200 EXPECT_TRUE(CoreAudioUtil::DeviceIsDefault(eRender, eConsole, id)); |
210 EXPECT_FALSE(CoreAudioUtil::DeviceIsDefault(eCapture, eConsole, id)); | 201 EXPECT_FALSE(CoreAudioUtil::DeviceIsDefault(eCapture, eConsole, id)); |
211 } | 202 } |
212 | 203 |
213 TEST_F(CoreAudioUtilWinTest, CreateDefaultClient) { | 204 TEST_F(CoreAudioUtilWinTest, CreateDefaultClient) { |
214 if (!CanRunAudioTest()) | 205 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
215 return; | |
216 | 206 |
217 EDataFlow data[] = {eRender, eCapture}; | 207 EDataFlow data[] = {eRender, eCapture}; |
218 | 208 |
219 for (int i = 0; i < arraysize(data); ++i) { | 209 for (int i = 0; i < arraysize(data); ++i) { |
220 ScopedComPtr<IAudioClient> client; | 210 ScopedComPtr<IAudioClient> client; |
221 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 211 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
222 EXPECT_TRUE(client.get()); | 212 EXPECT_TRUE(client.get()); |
223 } | 213 } |
224 } | 214 } |
225 | 215 |
226 TEST_F(CoreAudioUtilWinTest, CreateClient) { | 216 TEST_F(CoreAudioUtilWinTest, CreateClient) { |
227 if (!CanRunAudioTest()) | 217 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
228 return; | |
229 | 218 |
230 EDataFlow data[] = {eRender, eCapture}; | 219 EDataFlow data[] = {eRender, eCapture}; |
231 | 220 |
232 for (int i = 0; i < arraysize(data); ++i) { | 221 for (int i = 0; i < arraysize(data); ++i) { |
233 ScopedComPtr<IMMDevice> device; | 222 ScopedComPtr<IMMDevice> device; |
234 ScopedComPtr<IAudioClient> client; | 223 ScopedComPtr<IAudioClient> client; |
235 device = CoreAudioUtil::CreateDefaultDevice(data[i], eConsole); | 224 device = CoreAudioUtil::CreateDefaultDevice(data[i], eConsole); |
236 EXPECT_TRUE(device.get()); | 225 EXPECT_TRUE(device.get()); |
237 EXPECT_EQ(data[i], CoreAudioUtil::GetDataFlow(device.get())); | 226 EXPECT_EQ(data[i], CoreAudioUtil::GetDataFlow(device.get())); |
238 client = CoreAudioUtil::CreateClient(device.get()); | 227 client = CoreAudioUtil::CreateClient(device.get()); |
239 EXPECT_TRUE(client.get()); | 228 EXPECT_TRUE(client.get()); |
240 } | 229 } |
241 } | 230 } |
242 | 231 |
243 TEST_F(CoreAudioUtilWinTest, GetSharedModeMixFormat) { | 232 TEST_F(CoreAudioUtilWinTest, GetSharedModeMixFormat) { |
244 if (!CanRunAudioTest()) | 233 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
245 return; | |
246 | 234 |
247 ScopedComPtr<IMMDevice> device; | 235 ScopedComPtr<IMMDevice> device; |
248 ScopedComPtr<IAudioClient> client; | 236 ScopedComPtr<IAudioClient> client; |
249 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 237 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
250 EXPECT_TRUE(device.get()); | 238 EXPECT_TRUE(device.get()); |
251 client = CoreAudioUtil::CreateClient(device.get()); | 239 client = CoreAudioUtil::CreateClient(device.get()); |
252 EXPECT_TRUE(client.get()); | 240 EXPECT_TRUE(client.get()); |
253 | 241 |
254 // Perform a simple sanity test of the aquired format structure. | 242 // Perform a simple sanity test of the aquired format structure. |
255 WAVEFORMATPCMEX format; | 243 WAVEFORMATPCMEX format; |
256 EXPECT_TRUE( | 244 EXPECT_TRUE( |
257 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 245 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); |
258 EXPECT_GE(format.Format.nChannels, 1); | 246 EXPECT_GE(format.Format.nChannels, 1); |
259 EXPECT_GE(format.Format.nSamplesPerSec, 8000u); | 247 EXPECT_GE(format.Format.nSamplesPerSec, 8000u); |
260 EXPECT_GE(format.Format.wBitsPerSample, 16); | 248 EXPECT_GE(format.Format.wBitsPerSample, 16); |
261 EXPECT_GE(format.Samples.wValidBitsPerSample, 16); | 249 EXPECT_GE(format.Samples.wValidBitsPerSample, 16); |
262 EXPECT_EQ(format.Format.wFormatTag, WAVE_FORMAT_EXTENSIBLE); | 250 EXPECT_EQ(format.Format.wFormatTag, WAVE_FORMAT_EXTENSIBLE); |
263 } | 251 } |
264 | 252 |
265 TEST_F(CoreAudioUtilWinTest, IsChannelLayoutSupported) { | 253 TEST_F(CoreAudioUtilWinTest, IsChannelLayoutSupported) { |
266 if (!CanRunAudioTest()) | 254 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
267 return; | |
268 | 255 |
269 // The preferred channel layout should always be supported. Being supported | 256 // The preferred channel layout should always be supported. Being supported |
270 // means that it is possible to initialize a shared mode stream with the | 257 // means that it is possible to initialize a shared mode stream with the |
271 // particular channel layout. | 258 // particular channel layout. |
272 AudioParameters mix_params; | 259 AudioParameters mix_params; |
273 HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(eRender, eConsole, | 260 HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(eRender, eConsole, |
274 &mix_params); | 261 &mix_params); |
275 EXPECT_TRUE(SUCCEEDED(hr)); | 262 EXPECT_TRUE(SUCCEEDED(hr)); |
276 EXPECT_TRUE(mix_params.IsValid()); | 263 EXPECT_TRUE(mix_params.IsValid()); |
277 EXPECT_TRUE(CoreAudioUtil::IsChannelLayoutSupported( | 264 EXPECT_TRUE(CoreAudioUtil::IsChannelLayoutSupported( |
278 std::string(), eRender, eConsole, mix_params.channel_layout())); | 265 std::string(), eRender, eConsole, mix_params.channel_layout())); |
279 | 266 |
280 // Check if it is possible to modify the channel layout to stereo for a | 267 // Check if it is possible to modify the channel layout to stereo for a |
281 // device which reports that it prefers to be openen up in an other | 268 // device which reports that it prefers to be openen up in an other |
282 // channel configuration. | 269 // channel configuration. |
283 if (mix_params.channel_layout() != CHANNEL_LAYOUT_STEREO) { | 270 if (mix_params.channel_layout() != CHANNEL_LAYOUT_STEREO) { |
284 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; | 271 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; |
285 // TODO(henrika): it might be too pessimistic to assume false as return | 272 // TODO(henrika): it might be too pessimistic to assume false as return |
286 // value here. | 273 // value here. |
287 EXPECT_FALSE(CoreAudioUtil::IsChannelLayoutSupported( | 274 EXPECT_FALSE(CoreAudioUtil::IsChannelLayoutSupported( |
288 std::string(), eRender, eConsole, channel_layout)); | 275 std::string(), eRender, eConsole, channel_layout)); |
289 } | 276 } |
290 } | 277 } |
291 | 278 |
292 TEST_F(CoreAudioUtilWinTest, GetDevicePeriod) { | 279 TEST_F(CoreAudioUtilWinTest, GetDevicePeriod) { |
293 if (!CanRunAudioTest()) | 280 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
294 return; | |
295 | 281 |
296 EDataFlow data[] = {eRender, eCapture}; | 282 EDataFlow data[] = {eRender, eCapture}; |
297 | 283 |
298 // Verify that the device periods are valid for the default render and | 284 // Verify that the device periods are valid for the default render and |
299 // capture devices. | 285 // capture devices. |
300 for (int i = 0; i < arraysize(data); ++i) { | 286 for (int i = 0; i < arraysize(data); ++i) { |
301 ScopedComPtr<IAudioClient> client; | 287 ScopedComPtr<IAudioClient> client; |
302 REFERENCE_TIME shared_time_period = 0; | 288 REFERENCE_TIME shared_time_period = 0; |
303 REFERENCE_TIME exclusive_time_period = 0; | 289 REFERENCE_TIME exclusive_time_period = 0; |
304 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 290 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
305 EXPECT_TRUE(client.get()); | 291 EXPECT_TRUE(client.get()); |
306 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( | 292 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( |
307 client.get(), AUDCLNT_SHAREMODE_SHARED, &shared_time_period))); | 293 client.get(), AUDCLNT_SHAREMODE_SHARED, &shared_time_period))); |
308 EXPECT_GT(shared_time_period, 0); | 294 EXPECT_GT(shared_time_period, 0); |
309 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( | 295 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( |
310 client.get(), AUDCLNT_SHAREMODE_EXCLUSIVE, &exclusive_time_period))); | 296 client.get(), AUDCLNT_SHAREMODE_EXCLUSIVE, &exclusive_time_period))); |
311 EXPECT_GT(exclusive_time_period, 0); | 297 EXPECT_GT(exclusive_time_period, 0); |
312 EXPECT_LE(exclusive_time_period, shared_time_period); | 298 EXPECT_LE(exclusive_time_period, shared_time_period); |
313 } | 299 } |
314 } | 300 } |
315 | 301 |
316 TEST_F(CoreAudioUtilWinTest, GetPreferredAudioParameters) { | 302 TEST_F(CoreAudioUtilWinTest, GetPreferredAudioParameters) { |
317 if (!CanRunAudioTest()) | 303 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
318 return; | |
319 | 304 |
320 EDataFlow data[] = {eRender, eCapture}; | 305 EDataFlow data[] = {eRender, eCapture}; |
321 | 306 |
322 // Verify that the preferred audio parameters are OK for the default render | 307 // Verify that the preferred audio parameters are OK for the default render |
323 // and capture devices. | 308 // and capture devices. |
324 for (int i = 0; i < arraysize(data); ++i) { | 309 for (int i = 0; i < arraysize(data); ++i) { |
325 ScopedComPtr<IAudioClient> client; | 310 ScopedComPtr<IAudioClient> client; |
326 AudioParameters params; | 311 AudioParameters params; |
327 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 312 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
328 EXPECT_TRUE(client.get()); | 313 EXPECT_TRUE(client.get()); |
329 EXPECT_TRUE(SUCCEEDED( | 314 EXPECT_TRUE(SUCCEEDED( |
330 CoreAudioUtil::GetPreferredAudioParameters(client.get(), ¶ms))); | 315 CoreAudioUtil::GetPreferredAudioParameters(client.get(), ¶ms))); |
331 EXPECT_TRUE(params.IsValid()); | 316 EXPECT_TRUE(params.IsValid()); |
332 } | 317 } |
333 } | 318 } |
334 | 319 |
335 TEST_F(CoreAudioUtilWinTest, SharedModeInitialize) { | 320 TEST_F(CoreAudioUtilWinTest, SharedModeInitialize) { |
336 if (!CanRunAudioTest()) | 321 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
337 return; | |
338 | 322 |
339 ScopedComPtr<IAudioClient> client; | 323 ScopedComPtr<IAudioClient> client; |
340 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); | 324 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); |
341 EXPECT_TRUE(client.get()); | 325 EXPECT_TRUE(client.get()); |
342 | 326 |
343 WAVEFORMATPCMEX format; | 327 WAVEFORMATPCMEX format; |
344 EXPECT_TRUE( | 328 EXPECT_TRUE( |
345 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 329 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); |
346 | 330 |
347 // Perform a shared-mode initialization without event-driven buffer handling. | 331 // Perform a shared-mode initialization without event-driven buffer handling. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 373 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); |
390 EXPECT_TRUE(CoreAudioUtil::IsFormatSupported( | 374 EXPECT_TRUE(CoreAudioUtil::IsFormatSupported( |
391 client.get(), AUDCLNT_SHAREMODE_SHARED, &format)); | 375 client.get(), AUDCLNT_SHAREMODE_SHARED, &format)); |
392 hr = CoreAudioUtil::SharedModeInitialize( | 376 hr = CoreAudioUtil::SharedModeInitialize( |
393 client.get(), &format, event_handle.Get(), &endpoint_buffer_size, NULL); | 377 client.get(), &format, event_handle.Get(), &endpoint_buffer_size, NULL); |
394 EXPECT_TRUE(SUCCEEDED(hr)); | 378 EXPECT_TRUE(SUCCEEDED(hr)); |
395 EXPECT_GT(endpoint_buffer_size, 0u); | 379 EXPECT_GT(endpoint_buffer_size, 0u); |
396 } | 380 } |
397 | 381 |
398 TEST_F(CoreAudioUtilWinTest, CreateRenderAndCaptureClients) { | 382 TEST_F(CoreAudioUtilWinTest, CreateRenderAndCaptureClients) { |
399 if (!CanRunAudioTest()) | 383 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
400 return; | |
401 | 384 |
402 EDataFlow data[] = {eRender, eCapture}; | 385 EDataFlow data[] = {eRender, eCapture}; |
403 | 386 |
404 WAVEFORMATPCMEX format; | 387 WAVEFORMATPCMEX format; |
405 uint32 endpoint_buffer_size = 0; | 388 uint32 endpoint_buffer_size = 0; |
406 | 389 |
407 for (int i = 0; i < arraysize(data); ++i) { | 390 for (int i = 0; i < arraysize(data); ++i) { |
408 ScopedComPtr<IAudioClient> client; | 391 ScopedComPtr<IAudioClient> client; |
409 ScopedComPtr<IAudioRenderClient> render_client; | 392 ScopedComPtr<IAudioRenderClient> render_client; |
410 ScopedComPtr<IAudioCaptureClient> capture_client; | 393 ScopedComPtr<IAudioCaptureClient> capture_client; |
(...skipping 24 matching lines...) Expand all Loading... |
435 CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 418 CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, |
436 &endpoint_buffer_size, NULL); | 419 &endpoint_buffer_size, NULL); |
437 capture_client = CoreAudioUtil::CreateCaptureClient(client.get()); | 420 capture_client = CoreAudioUtil::CreateCaptureClient(client.get()); |
438 EXPECT_TRUE(capture_client.get()); | 421 EXPECT_TRUE(capture_client.get()); |
439 EXPECT_GT(endpoint_buffer_size, 0u); | 422 EXPECT_GT(endpoint_buffer_size, 0u); |
440 } | 423 } |
441 } | 424 } |
442 } | 425 } |
443 | 426 |
444 TEST_F(CoreAudioUtilWinTest, FillRenderEndpointBufferWithSilence) { | 427 TEST_F(CoreAudioUtilWinTest, FillRenderEndpointBufferWithSilence) { |
445 if (!CanRunAudioTest()) | 428 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
446 return; | |
447 | 429 |
448 // Create default clients using the default mixing format for shared mode. | 430 // Create default clients using the default mixing format for shared mode. |
449 ScopedComPtr<IAudioClient> client( | 431 ScopedComPtr<IAudioClient> client( |
450 CoreAudioUtil::CreateDefaultClient(eRender, eConsole)); | 432 CoreAudioUtil::CreateDefaultClient(eRender, eConsole)); |
451 EXPECT_TRUE(client.get()); | 433 EXPECT_TRUE(client.get()); |
452 | 434 |
453 WAVEFORMATPCMEX format; | 435 WAVEFORMATPCMEX format; |
454 uint32 endpoint_buffer_size = 0; | 436 uint32 endpoint_buffer_size = 0; |
455 EXPECT_TRUE( | 437 EXPECT_TRUE( |
456 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 438 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); |
(...skipping 14 matching lines...) Expand all Loading... |
471 // Fill it up with zeros and verify that the buffer is full. | 453 // Fill it up with zeros and verify that the buffer is full. |
472 // It is not possible to verify that the actual data consists of zeros | 454 // It is not possible to verify that the actual data consists of zeros |
473 // since we can't access data that has already been sent to the endpoint | 455 // since we can't access data that has already been sent to the endpoint |
474 // buffer. | 456 // buffer. |
475 EXPECT_TRUE(CoreAudioUtil::FillRenderEndpointBufferWithSilence( | 457 EXPECT_TRUE(CoreAudioUtil::FillRenderEndpointBufferWithSilence( |
476 client.get(), render_client.get())); | 458 client.get(), render_client.get())); |
477 client->GetCurrentPadding(&num_queued_frames); | 459 client->GetCurrentPadding(&num_queued_frames); |
478 EXPECT_EQ(num_queued_frames, endpoint_buffer_size); | 460 EXPECT_EQ(num_queued_frames, endpoint_buffer_size); |
479 } | 461 } |
480 | 462 |
481 // This test can only succeed on a machine that has audio hardware | 463 // This test can only run on a machine that has audio hardware |
482 // that has both input and output devices. Currently this is the case | 464 // that has both input and output devices. |
483 // with our test bots and the CanRunAudioTest() method should make sure | |
484 // that the test won't run in unsupported environments, but be warned. | |
485 TEST_F(CoreAudioUtilWinTest, GetMatchingOutputDeviceID) { | 465 TEST_F(CoreAudioUtilWinTest, GetMatchingOutputDeviceID) { |
486 if (!CanRunAudioTest()) | 466 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
487 return; | |
488 | 467 |
489 bool found_a_pair = false; | 468 bool found_a_pair = false; |
490 | 469 |
491 ScopedComPtr<IMMDeviceEnumerator> enumerator( | 470 ScopedComPtr<IMMDeviceEnumerator> enumerator( |
492 CoreAudioUtil::CreateDeviceEnumerator()); | 471 CoreAudioUtil::CreateDeviceEnumerator()); |
493 ASSERT_TRUE(enumerator.get()); | 472 ASSERT_TRUE(enumerator.get()); |
494 | 473 |
495 // Enumerate all active input and output devices and fetch the ID of | 474 // Enumerate all active input and output devices and fetch the ID of |
496 // the associated device. | 475 // the associated device. |
497 ScopedComPtr<IMMDeviceCollection> collection; | 476 ScopedComPtr<IMMDeviceCollection> collection; |
498 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(eCapture, | 477 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(eCapture, |
499 DEVICE_STATE_ACTIVE, collection.Receive()))); | 478 DEVICE_STATE_ACTIVE, collection.Receive()))); |
500 UINT count = 0; | 479 UINT count = 0; |
501 collection->GetCount(&count); | 480 collection->GetCount(&count); |
502 for (UINT i = 0; i < count && !found_a_pair; ++i) { | 481 for (UINT i = 0; i < count && !found_a_pair; ++i) { |
503 ScopedComPtr<IMMDevice> device; | 482 ScopedComPtr<IMMDevice> device; |
504 collection->Item(i, device.Receive()); | 483 collection->Item(i, device.Receive()); |
505 base::win::ScopedCoMem<WCHAR> wide_id; | 484 base::win::ScopedCoMem<WCHAR> wide_id; |
506 device->GetId(&wide_id); | 485 device->GetId(&wide_id); |
507 std::string id; | 486 std::string id; |
508 base::WideToUTF8(wide_id, wcslen(wide_id), &id); | 487 base::WideToUTF8(wide_id, wcslen(wide_id), &id); |
509 found_a_pair = !CoreAudioUtil::GetMatchingOutputDeviceID(id).empty(); | 488 found_a_pair = !CoreAudioUtil::GetMatchingOutputDeviceID(id).empty(); |
510 } | 489 } |
511 | 490 |
512 EXPECT_TRUE(found_a_pair); | 491 EXPECT_TRUE(found_a_pair); |
513 } | 492 } |
514 | 493 |
515 TEST_F(CoreAudioUtilWinTest, GetDefaultOutputDeviceID) { | 494 TEST_F(CoreAudioUtilWinTest, GetDefaultOutputDeviceID) { |
516 if (!CanRunAudioTest()) | 495 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
517 return; | |
518 | 496 |
519 std::string default_device_id(CoreAudioUtil::GetDefaultOutputDeviceID()); | 497 std::string default_device_id(CoreAudioUtil::GetDefaultOutputDeviceID()); |
520 EXPECT_FALSE(default_device_id.empty()); | 498 EXPECT_FALSE(default_device_id.empty()); |
521 } | 499 } |
522 | 500 |
523 } // namespace media | 501 } // namespace media |
OLD | NEW |