| 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 "media/audio/win/core_audio_util_win.h" | 5 #include "media/audio/win/core_audio_util_win.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 EXPECT_GT(capture_devices, 0); | 58 EXPECT_GT(capture_devices, 0); |
| 59 int total_devices = CoreAudioUtil::NumberOfActiveDevices(eAll); | 59 int total_devices = CoreAudioUtil::NumberOfActiveDevices(eAll); |
| 60 EXPECT_EQ(total_devices, render_devices + capture_devices); | 60 EXPECT_EQ(total_devices, render_devices + capture_devices); |
| 61 } | 61 } |
| 62 | 62 |
| 63 TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) { | 63 TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) { |
| 64 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 64 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 65 | 65 |
| 66 ScopedComPtr<IMMDeviceEnumerator> enumerator = | 66 ScopedComPtr<IMMDeviceEnumerator> enumerator = |
| 67 CoreAudioUtil::CreateDeviceEnumerator(); | 67 CoreAudioUtil::CreateDeviceEnumerator(); |
| 68 EXPECT_TRUE(enumerator.get()); | 68 EXPECT_TRUE(enumerator.Get()); |
| 69 } | 69 } |
| 70 | 70 |
| 71 TEST_F(CoreAudioUtilWinTest, CreateDefaultDevice) { | 71 TEST_F(CoreAudioUtilWinTest, CreateDefaultDevice) { |
| 72 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 72 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 73 | 73 |
| 74 struct { | 74 struct { |
| 75 EDataFlow flow; | 75 EDataFlow flow; |
| 76 ERole role; | 76 ERole role; |
| 77 } data[] = { | 77 } data[] = { |
| 78 {eRender, eConsole}, | 78 {eRender, eConsole}, |
| 79 {eRender, eCommunications}, | 79 {eRender, eCommunications}, |
| 80 {eRender, eMultimedia}, | 80 {eRender, eMultimedia}, |
| 81 {eCapture, eConsole}, | 81 {eCapture, eConsole}, |
| 82 {eCapture, eCommunications}, | 82 {eCapture, eCommunications}, |
| 83 {eCapture, eMultimedia} | 83 {eCapture, eMultimedia} |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 // Create default devices for all flow/role combinations above. | 86 // Create default devices for all flow/role combinations above. |
| 87 ScopedComPtr<IMMDevice> audio_device; | 87 ScopedComPtr<IMMDevice> audio_device; |
| 88 for (size_t i = 0; i < arraysize(data); ++i) { | 88 for (size_t i = 0; i < arraysize(data); ++i) { |
| 89 audio_device = | 89 audio_device = |
| 90 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); | 90 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); |
| 91 EXPECT_TRUE(audio_device.get()); | 91 EXPECT_TRUE(audio_device.Get()); |
| 92 EXPECT_EQ(data[i].flow, CoreAudioUtil::GetDataFlow(audio_device.get())); | 92 EXPECT_EQ(data[i].flow, CoreAudioUtil::GetDataFlow(audio_device.Get())); |
| 93 } | 93 } |
| 94 | 94 |
| 95 // Only eRender and eCapture are allowed as flow parameter. | 95 // Only eRender and eCapture are allowed as flow parameter. |
| 96 audio_device = CoreAudioUtil::CreateDefaultDevice(eAll, eConsole); | 96 audio_device = CoreAudioUtil::CreateDefaultDevice(eAll, eConsole); |
| 97 EXPECT_FALSE(audio_device.get()); | 97 EXPECT_FALSE(audio_device.Get()); |
| 98 } | 98 } |
| 99 | 99 |
| 100 TEST_F(CoreAudioUtilWinTest, CreateDevice) { | 100 TEST_F(CoreAudioUtilWinTest, CreateDevice) { |
| 101 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 101 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 102 | 102 |
| 103 // Get name and ID of default device used for playback. | 103 // Get name and ID of default device used for playback. |
| 104 ScopedComPtr<IMMDevice> default_render_device = | 104 ScopedComPtr<IMMDevice> default_render_device = |
| 105 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 105 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
| 106 AudioDeviceName default_render_name; | 106 AudioDeviceName default_render_name; |
| 107 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName( | 107 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName( |
| 108 default_render_device.get(), &default_render_name))); | 108 default_render_device.Get(), &default_render_name))); |
| 109 | 109 |
| 110 // Use the uniqe ID as input to CreateDevice() and create a corresponding | 110 // Use the uniqe ID as input to CreateDevice() and create a corresponding |
| 111 // IMMDevice. | 111 // IMMDevice. |
| 112 ScopedComPtr<IMMDevice> audio_device = | 112 ScopedComPtr<IMMDevice> audio_device = |
| 113 CoreAudioUtil::CreateDevice(default_render_name.unique_id); | 113 CoreAudioUtil::CreateDevice(default_render_name.unique_id); |
| 114 EXPECT_TRUE(audio_device.get()); | 114 EXPECT_TRUE(audio_device.Get()); |
| 115 | 115 |
| 116 // Verify that the two IMMDevice interfaces represents the same endpoint | 116 // Verify that the two IMMDevice interfaces represents the same endpoint |
| 117 // by comparing their unique IDs. | 117 // by comparing their unique IDs. |
| 118 AudioDeviceName device_name; | 118 AudioDeviceName device_name; |
| 119 EXPECT_TRUE(SUCCEEDED( | 119 EXPECT_TRUE(SUCCEEDED( |
| 120 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); | 120 CoreAudioUtil::GetDeviceName(audio_device.Get(), &device_name))); |
| 121 EXPECT_EQ(default_render_name.unique_id, device_name.unique_id); | 121 EXPECT_EQ(default_render_name.unique_id, device_name.unique_id); |
| 122 } | 122 } |
| 123 | 123 |
| 124 TEST_F(CoreAudioUtilWinTest, GetDefaultDeviceName) { | 124 TEST_F(CoreAudioUtilWinTest, GetDefaultDeviceName) { |
| 125 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 125 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 126 | 126 |
| 127 struct { | 127 struct { |
| 128 EDataFlow flow; | 128 EDataFlow flow; |
| 129 ERole role; | 129 ERole role; |
| 130 } data[] = { | 130 } data[] = { |
| 131 {eRender, eConsole}, | 131 {eRender, eConsole}, |
| 132 {eRender, eCommunications}, | 132 {eRender, eCommunications}, |
| 133 {eCapture, eConsole}, | 133 {eCapture, eConsole}, |
| 134 {eCapture, eCommunications} | 134 {eCapture, eCommunications} |
| 135 }; | 135 }; |
| 136 | 136 |
| 137 // Get name and ID of default devices for all flow/role combinations above. | 137 // Get name and ID of default devices for all flow/role combinations above. |
| 138 ScopedComPtr<IMMDevice> audio_device; | 138 ScopedComPtr<IMMDevice> audio_device; |
| 139 AudioDeviceName device_name; | 139 AudioDeviceName device_name; |
| 140 for (size_t i = 0; i < arraysize(data); ++i) { | 140 for (size_t i = 0; i < arraysize(data); ++i) { |
| 141 audio_device = | 141 audio_device = |
| 142 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); | 142 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); |
| 143 EXPECT_TRUE(SUCCEEDED( | 143 EXPECT_TRUE(SUCCEEDED( |
| 144 CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name))); | 144 CoreAudioUtil::GetDeviceName(audio_device.Get(), &device_name))); |
| 145 EXPECT_FALSE(device_name.device_name.empty()); | 145 EXPECT_FALSE(device_name.device_name.empty()); |
| 146 EXPECT_FALSE(device_name.unique_id.empty()); | 146 EXPECT_FALSE(device_name.unique_id.empty()); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 TEST_F(CoreAudioUtilWinTest, GetAudioControllerID) { | 150 TEST_F(CoreAudioUtilWinTest, GetAudioControllerID) { |
| 151 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 151 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 152 | 152 |
| 153 ScopedComPtr<IMMDeviceEnumerator> enumerator( | 153 ScopedComPtr<IMMDeviceEnumerator> enumerator( |
| 154 CoreAudioUtil::CreateDeviceEnumerator()); | 154 CoreAudioUtil::CreateDeviceEnumerator()); |
| 155 ASSERT_TRUE(enumerator.get()); | 155 ASSERT_TRUE(enumerator.Get()); |
| 156 | 156 |
| 157 // Enumerate all active input and output devices and fetch the ID of | 157 // Enumerate all active input and output devices and fetch the ID of |
| 158 // the associated device. | 158 // the associated device. |
| 159 EDataFlow flows[] = { eRender , eCapture }; | 159 EDataFlow flows[] = { eRender , eCapture }; |
| 160 for (size_t i = 0; i < arraysize(flows); ++i) { | 160 for (size_t i = 0; i < arraysize(flows); ++i) { |
| 161 ScopedComPtr<IMMDeviceCollection> collection; | 161 ScopedComPtr<IMMDeviceCollection> collection; |
| 162 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(flows[i], | 162 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(flows[i], |
| 163 DEVICE_STATE_ACTIVE, collection.Receive()))); | 163 DEVICE_STATE_ACTIVE, collection.Receive()))); |
| 164 UINT count = 0; | 164 UINT count = 0; |
| 165 collection->GetCount(&count); | 165 collection->GetCount(&count); |
| 166 for (UINT j = 0; j < count; ++j) { | 166 for (UINT j = 0; j < count; ++j) { |
| 167 ScopedComPtr<IMMDevice> device; | 167 ScopedComPtr<IMMDevice> device; |
| 168 collection->Item(j, device.Receive()); | 168 collection->Item(j, device.Receive()); |
| 169 std::string controller_id( | 169 std::string controller_id( |
| 170 CoreAudioUtil::GetAudioControllerID(device.get(), enumerator.get())); | 170 CoreAudioUtil::GetAudioControllerID(device.Get(), enumerator.Get())); |
| 171 EXPECT_FALSE(controller_id.empty()); | 171 EXPECT_FALSE(controller_id.empty()); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 TEST_F(CoreAudioUtilWinTest, GetFriendlyName) { | 176 TEST_F(CoreAudioUtilWinTest, GetFriendlyName) { |
| 177 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 177 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 178 | 178 |
| 179 // Get name and ID of default device used for recording. | 179 // Get name and ID of default device used for recording. |
| 180 ScopedComPtr<IMMDevice> audio_device = | 180 ScopedComPtr<IMMDevice> audio_device = |
| 181 CoreAudioUtil::CreateDefaultDevice(eCapture, eConsole); | 181 CoreAudioUtil::CreateDefaultDevice(eCapture, eConsole); |
| 182 AudioDeviceName device_name; | 182 AudioDeviceName device_name; |
| 183 HRESULT hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); | 183 HRESULT hr = CoreAudioUtil::GetDeviceName(audio_device.Get(), &device_name); |
| 184 EXPECT_TRUE(SUCCEEDED(hr)); | 184 EXPECT_TRUE(SUCCEEDED(hr)); |
| 185 | 185 |
| 186 // Use unique ID as input to GetFriendlyName() and compare the result | 186 // Use unique ID as input to GetFriendlyName() and compare the result |
| 187 // with the already obtained friendly name for the default capture device. | 187 // with the already obtained friendly name for the default capture device. |
| 188 std::string friendly_name = CoreAudioUtil::GetFriendlyName( | 188 std::string friendly_name = CoreAudioUtil::GetFriendlyName( |
| 189 device_name.unique_id); | 189 device_name.unique_id); |
| 190 EXPECT_EQ(friendly_name, device_name.device_name); | 190 EXPECT_EQ(friendly_name, device_name.device_name); |
| 191 | 191 |
| 192 // Same test as above but for playback. | 192 // Same test as above but for playback. |
| 193 audio_device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 193 audio_device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
| 194 hr = CoreAudioUtil::GetDeviceName(audio_device.get(), &device_name); | 194 hr = CoreAudioUtil::GetDeviceName(audio_device.Get(), &device_name); |
| 195 EXPECT_TRUE(SUCCEEDED(hr)); | 195 EXPECT_TRUE(SUCCEEDED(hr)); |
| 196 friendly_name = CoreAudioUtil::GetFriendlyName(device_name.unique_id); | 196 friendly_name = CoreAudioUtil::GetFriendlyName(device_name.unique_id); |
| 197 EXPECT_EQ(friendly_name, device_name.device_name); | 197 EXPECT_EQ(friendly_name, device_name.device_name); |
| 198 } | 198 } |
| 199 | 199 |
| 200 TEST_F(CoreAudioUtilWinTest, DeviceIsDefault) { | 200 TEST_F(CoreAudioUtilWinTest, DeviceIsDefault) { |
| 201 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 201 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 202 | 202 |
| 203 // Verify that the default render device is correctly identified as a | 203 // Verify that the default render device is correctly identified as a |
| 204 // default device. | 204 // default device. |
| 205 ScopedComPtr<IMMDevice> audio_device = | 205 ScopedComPtr<IMMDevice> audio_device = |
| 206 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 206 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
| 207 AudioDeviceName name; | 207 AudioDeviceName name; |
| 208 EXPECT_TRUE( | 208 EXPECT_TRUE( |
| 209 SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device.get(), &name))); | 209 SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device.Get(), &name))); |
| 210 const std::string id = name.unique_id; | 210 const std::string id = name.unique_id; |
| 211 EXPECT_TRUE(CoreAudioUtil::DeviceIsDefault(eRender, eConsole, id)); | 211 EXPECT_TRUE(CoreAudioUtil::DeviceIsDefault(eRender, eConsole, id)); |
| 212 EXPECT_FALSE(CoreAudioUtil::DeviceIsDefault(eCapture, eConsole, id)); | 212 EXPECT_FALSE(CoreAudioUtil::DeviceIsDefault(eCapture, eConsole, id)); |
| 213 } | 213 } |
| 214 | 214 |
| 215 TEST_F(CoreAudioUtilWinTest, CreateDefaultClient) { | 215 TEST_F(CoreAudioUtilWinTest, CreateDefaultClient) { |
| 216 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 216 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 217 | 217 |
| 218 EDataFlow data[] = {eRender, eCapture}; | 218 EDataFlow data[] = {eRender, eCapture}; |
| 219 | 219 |
| 220 for (size_t i = 0; i < arraysize(data); ++i) { | 220 for (size_t i = 0; i < arraysize(data); ++i) { |
| 221 ScopedComPtr<IAudioClient> client; | 221 ScopedComPtr<IAudioClient> client; |
| 222 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 222 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
| 223 EXPECT_TRUE(client.get()); | 223 EXPECT_TRUE(client.Get()); |
| 224 } | 224 } |
| 225 } | 225 } |
| 226 | 226 |
| 227 TEST_F(CoreAudioUtilWinTest, CreateClient) { | 227 TEST_F(CoreAudioUtilWinTest, CreateClient) { |
| 228 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 228 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 229 | 229 |
| 230 EDataFlow data[] = {eRender, eCapture}; | 230 EDataFlow data[] = {eRender, eCapture}; |
| 231 | 231 |
| 232 for (size_t i = 0; i < arraysize(data); ++i) { | 232 for (size_t i = 0; i < arraysize(data); ++i) { |
| 233 ScopedComPtr<IMMDevice> device; | 233 ScopedComPtr<IMMDevice> device; |
| 234 ScopedComPtr<IAudioClient> client; | 234 ScopedComPtr<IAudioClient> client; |
| 235 device = CoreAudioUtil::CreateDefaultDevice(data[i], eConsole); | 235 device = CoreAudioUtil::CreateDefaultDevice(data[i], eConsole); |
| 236 EXPECT_TRUE(device.get()); | 236 EXPECT_TRUE(device.Get()); |
| 237 EXPECT_EQ(data[i], CoreAudioUtil::GetDataFlow(device.get())); | 237 EXPECT_EQ(data[i], CoreAudioUtil::GetDataFlow(device.Get())); |
| 238 client = CoreAudioUtil::CreateClient(device.get()); | 238 client = CoreAudioUtil::CreateClient(device.Get()); |
| 239 EXPECT_TRUE(client.get()); | 239 EXPECT_TRUE(client.Get()); |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 | 242 |
| 243 TEST_F(CoreAudioUtilWinTest, GetSharedModeMixFormat) { | 243 TEST_F(CoreAudioUtilWinTest, GetSharedModeMixFormat) { |
| 244 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 244 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 245 | 245 |
| 246 ScopedComPtr<IMMDevice> device; | 246 ScopedComPtr<IMMDevice> device; |
| 247 ScopedComPtr<IAudioClient> client; | 247 ScopedComPtr<IAudioClient> client; |
| 248 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 248 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
| 249 EXPECT_TRUE(device.get()); | 249 EXPECT_TRUE(device.Get()); |
| 250 client = CoreAudioUtil::CreateClient(device.get()); | 250 client = CoreAudioUtil::CreateClient(device.Get()); |
| 251 EXPECT_TRUE(client.get()); | 251 EXPECT_TRUE(client.Get()); |
| 252 | 252 |
| 253 // Perform a simple sanity test of the aquired format structure. | 253 // Perform a simple sanity test of the aquired format structure. |
| 254 WAVEFORMATPCMEX format; | 254 WAVEFORMATPCMEX format; |
| 255 EXPECT_TRUE( | 255 EXPECT_TRUE( |
| 256 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 256 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.Get(), &format))); |
| 257 EXPECT_GE(format.Format.nChannels, 1); | 257 EXPECT_GE(format.Format.nChannels, 1); |
| 258 EXPECT_GE(format.Format.nSamplesPerSec, 8000u); | 258 EXPECT_GE(format.Format.nSamplesPerSec, 8000u); |
| 259 EXPECT_GE(format.Format.wBitsPerSample, 16); | 259 EXPECT_GE(format.Format.wBitsPerSample, 16); |
| 260 EXPECT_GE(format.Samples.wValidBitsPerSample, 16); | 260 EXPECT_GE(format.Samples.wValidBitsPerSample, 16); |
| 261 EXPECT_EQ(format.Format.wFormatTag, WAVE_FORMAT_EXTENSIBLE); | 261 EXPECT_EQ(format.Format.wFormatTag, WAVE_FORMAT_EXTENSIBLE); |
| 262 } | 262 } |
| 263 | 263 |
| 264 TEST_F(CoreAudioUtilWinTest, IsChannelLayoutSupported) { | 264 TEST_F(CoreAudioUtilWinTest, IsChannelLayoutSupported) { |
| 265 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 265 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 266 | 266 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 292 | 292 |
| 293 EDataFlow data[] = {eRender, eCapture}; | 293 EDataFlow data[] = {eRender, eCapture}; |
| 294 | 294 |
| 295 // Verify that the device periods are valid for the default render and | 295 // Verify that the device periods are valid for the default render and |
| 296 // capture devices. | 296 // capture devices. |
| 297 for (size_t i = 0; i < arraysize(data); ++i) { | 297 for (size_t i = 0; i < arraysize(data); ++i) { |
| 298 ScopedComPtr<IAudioClient> client; | 298 ScopedComPtr<IAudioClient> client; |
| 299 REFERENCE_TIME shared_time_period = 0; | 299 REFERENCE_TIME shared_time_period = 0; |
| 300 REFERENCE_TIME exclusive_time_period = 0; | 300 REFERENCE_TIME exclusive_time_period = 0; |
| 301 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 301 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
| 302 EXPECT_TRUE(client.get()); | 302 EXPECT_TRUE(client.Get()); |
| 303 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( | 303 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( |
| 304 client.get(), AUDCLNT_SHAREMODE_SHARED, &shared_time_period))); | 304 client.Get(), AUDCLNT_SHAREMODE_SHARED, &shared_time_period))); |
| 305 EXPECT_GT(shared_time_period, 0); | 305 EXPECT_GT(shared_time_period, 0); |
| 306 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( | 306 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDevicePeriod( |
| 307 client.get(), AUDCLNT_SHAREMODE_EXCLUSIVE, &exclusive_time_period))); | 307 client.Get(), AUDCLNT_SHAREMODE_EXCLUSIVE, &exclusive_time_period))); |
| 308 EXPECT_GT(exclusive_time_period, 0); | 308 EXPECT_GT(exclusive_time_period, 0); |
| 309 EXPECT_LE(exclusive_time_period, shared_time_period); | 309 EXPECT_LE(exclusive_time_period, shared_time_period); |
| 310 } | 310 } |
| 311 } | 311 } |
| 312 | 312 |
| 313 TEST_F(CoreAudioUtilWinTest, GetPreferredAudioParameters) { | 313 TEST_F(CoreAudioUtilWinTest, GetPreferredAudioParameters) { |
| 314 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 314 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 315 | 315 |
| 316 EDataFlow data[] = {eRender, eCapture}; | 316 EDataFlow data[] = {eRender, eCapture}; |
| 317 | 317 |
| 318 // Verify that the preferred audio parameters are OK for the default render | 318 // Verify that the preferred audio parameters are OK for the default render |
| 319 // and capture devices. | 319 // and capture devices. |
| 320 for (size_t i = 0; i < arraysize(data); ++i) { | 320 for (size_t i = 0; i < arraysize(data); ++i) { |
| 321 ScopedComPtr<IAudioClient> client; | 321 ScopedComPtr<IAudioClient> client; |
| 322 AudioParameters params; | 322 AudioParameters params; |
| 323 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 323 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
| 324 EXPECT_TRUE(client.get()); | 324 EXPECT_TRUE(client.Get()); |
| 325 EXPECT_TRUE(SUCCEEDED( | 325 EXPECT_TRUE(SUCCEEDED( |
| 326 CoreAudioUtil::GetPreferredAudioParameters(client.get(), ¶ms))); | 326 CoreAudioUtil::GetPreferredAudioParameters(client.Get(), ¶ms))); |
| 327 EXPECT_TRUE(params.IsValid()); | 327 EXPECT_TRUE(params.IsValid()); |
| 328 } | 328 } |
| 329 } | 329 } |
| 330 | 330 |
| 331 TEST_F(CoreAudioUtilWinTest, SharedModeInitialize) { | 331 TEST_F(CoreAudioUtilWinTest, SharedModeInitialize) { |
| 332 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 332 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 333 | 333 |
| 334 ScopedComPtr<IAudioClient> client; | 334 ScopedComPtr<IAudioClient> client; |
| 335 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); | 335 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); |
| 336 EXPECT_TRUE(client.get()); | 336 EXPECT_TRUE(client.Get()); |
| 337 | 337 |
| 338 WAVEFORMATPCMEX format; | 338 WAVEFORMATPCMEX format; |
| 339 EXPECT_TRUE( | 339 EXPECT_TRUE( |
| 340 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 340 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.Get(), &format))); |
| 341 | 341 |
| 342 // Perform a shared-mode initialization without event-driven buffer handling. | 342 // Perform a shared-mode initialization without event-driven buffer handling. |
| 343 uint32_t endpoint_buffer_size = 0; | 343 uint32_t endpoint_buffer_size = 0; |
| 344 HRESULT hr = CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 344 HRESULT hr = CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 345 &endpoint_buffer_size, NULL); | 345 &endpoint_buffer_size, NULL); |
| 346 EXPECT_TRUE(SUCCEEDED(hr)); | 346 EXPECT_TRUE(SUCCEEDED(hr)); |
| 347 EXPECT_GT(endpoint_buffer_size, 0u); | 347 EXPECT_GT(endpoint_buffer_size, 0u); |
| 348 | 348 |
| 349 // It is only possible to create a client once. | 349 // It is only possible to create a client once. |
| 350 hr = CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 350 hr = CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 351 &endpoint_buffer_size, NULL); | 351 &endpoint_buffer_size, NULL); |
| 352 EXPECT_FALSE(SUCCEEDED(hr)); | 352 EXPECT_FALSE(SUCCEEDED(hr)); |
| 353 EXPECT_EQ(hr, AUDCLNT_E_ALREADY_INITIALIZED); | 353 EXPECT_EQ(hr, AUDCLNT_E_ALREADY_INITIALIZED); |
| 354 | 354 |
| 355 // Verify that it is possible to reinitialize the client after releasing it. | 355 // Verify that it is possible to reinitialize the client after releasing it. |
| 356 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); | 356 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); |
| 357 EXPECT_TRUE(client.get()); | 357 EXPECT_TRUE(client.Get()); |
| 358 hr = CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 358 hr = CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 359 &endpoint_buffer_size, NULL); | 359 &endpoint_buffer_size, NULL); |
| 360 EXPECT_TRUE(SUCCEEDED(hr)); | 360 EXPECT_TRUE(SUCCEEDED(hr)); |
| 361 EXPECT_GT(endpoint_buffer_size, 0u); | 361 EXPECT_GT(endpoint_buffer_size, 0u); |
| 362 | 362 |
| 363 // Use a non-supported format and verify that initialization fails. | 363 // Use a non-supported format and verify that initialization fails. |
| 364 // A simple way to emulate an invalid format is to use the shared-mode | 364 // A simple way to emulate an invalid format is to use the shared-mode |
| 365 // mixing format and modify the preferred sample. | 365 // mixing format and modify the preferred sample. |
| 366 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); | 366 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); |
| 367 EXPECT_TRUE(client.get()); | 367 EXPECT_TRUE(client.Get()); |
| 368 format.Format.nSamplesPerSec = format.Format.nSamplesPerSec + 1; | 368 format.Format.nSamplesPerSec = format.Format.nSamplesPerSec + 1; |
| 369 EXPECT_FALSE(CoreAudioUtil::IsFormatSupported( | 369 EXPECT_FALSE(CoreAudioUtil::IsFormatSupported( |
| 370 client.get(), AUDCLNT_SHAREMODE_SHARED, &format)); | 370 client.Get(), AUDCLNT_SHAREMODE_SHARED, &format)); |
| 371 hr = CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 371 hr = CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 372 &endpoint_buffer_size, NULL); | 372 &endpoint_buffer_size, NULL); |
| 373 EXPECT_TRUE(FAILED(hr)); | 373 EXPECT_TRUE(FAILED(hr)); |
| 374 EXPECT_EQ(hr, E_INVALIDARG); | 374 EXPECT_EQ(hr, E_INVALIDARG); |
| 375 | 375 |
| 376 // Finally, perform a shared-mode initialization using event-driven buffer | 376 // Finally, perform a shared-mode initialization using event-driven buffer |
| 377 // handling. The event handle will be signaled when an audio buffer is ready | 377 // handling. The event handle will be signaled when an audio buffer is ready |
| 378 // to be processed by the client (not verified here). | 378 // to be processed by the client (not verified here). |
| 379 // The event handle should be in the nonsignaled state. | 379 // The event handle should be in the nonsignaled state. |
| 380 base::win::ScopedHandle event_handle(::CreateEvent(NULL, TRUE, FALSE, NULL)); | 380 base::win::ScopedHandle event_handle(::CreateEvent(NULL, TRUE, FALSE, NULL)); |
| 381 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); | 381 client = CoreAudioUtil::CreateDefaultClient(eRender, eConsole); |
| 382 EXPECT_TRUE(client.get()); | 382 EXPECT_TRUE(client.Get()); |
| 383 EXPECT_TRUE( | 383 EXPECT_TRUE( |
| 384 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 384 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.Get(), &format))); |
| 385 EXPECT_TRUE(CoreAudioUtil::IsFormatSupported( | 385 EXPECT_TRUE(CoreAudioUtil::IsFormatSupported( |
| 386 client.get(), AUDCLNT_SHAREMODE_SHARED, &format)); | 386 client.Get(), AUDCLNT_SHAREMODE_SHARED, &format)); |
| 387 hr = CoreAudioUtil::SharedModeInitialize( | 387 hr = CoreAudioUtil::SharedModeInitialize( |
| 388 client.get(), &format, event_handle.Get(), &endpoint_buffer_size, NULL); | 388 client.Get(), &format, event_handle.Get(), &endpoint_buffer_size, NULL); |
| 389 EXPECT_TRUE(SUCCEEDED(hr)); | 389 EXPECT_TRUE(SUCCEEDED(hr)); |
| 390 EXPECT_GT(endpoint_buffer_size, 0u); | 390 EXPECT_GT(endpoint_buffer_size, 0u); |
| 391 } | 391 } |
| 392 | 392 |
| 393 TEST_F(CoreAudioUtilWinTest, CreateRenderAndCaptureClients) { | 393 TEST_F(CoreAudioUtilWinTest, CreateRenderAndCaptureClients) { |
| 394 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 394 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 395 | 395 |
| 396 EDataFlow data[] = {eRender, eCapture}; | 396 EDataFlow data[] = {eRender, eCapture}; |
| 397 | 397 |
| 398 WAVEFORMATPCMEX format; | 398 WAVEFORMATPCMEX format; |
| 399 uint32_t endpoint_buffer_size = 0; | 399 uint32_t endpoint_buffer_size = 0; |
| 400 | 400 |
| 401 for (size_t i = 0; i < arraysize(data); ++i) { | 401 for (size_t i = 0; i < arraysize(data); ++i) { |
| 402 ScopedComPtr<IAudioClient> client; | 402 ScopedComPtr<IAudioClient> client; |
| 403 ScopedComPtr<IAudioRenderClient> render_client; | 403 ScopedComPtr<IAudioRenderClient> render_client; |
| 404 ScopedComPtr<IAudioCaptureClient> capture_client; | 404 ScopedComPtr<IAudioCaptureClient> capture_client; |
| 405 | 405 |
| 406 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); | 406 client = CoreAudioUtil::CreateDefaultClient(data[i], eConsole); |
| 407 EXPECT_TRUE(client.get()); | 407 EXPECT_TRUE(client.Get()); |
| 408 EXPECT_TRUE(SUCCEEDED( | 408 EXPECT_TRUE(SUCCEEDED( |
| 409 CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 409 CoreAudioUtil::GetSharedModeMixFormat(client.Get(), &format))); |
| 410 if (data[i] == eRender) { | 410 if (data[i] == eRender) { |
| 411 // It is not possible to create a render client using an unitialized | 411 // It is not possible to create a render client using an unitialized |
| 412 // client interface. | 412 // client interface. |
| 413 render_client = CoreAudioUtil::CreateRenderClient(client.get()); | 413 render_client = CoreAudioUtil::CreateRenderClient(client.Get()); |
| 414 EXPECT_FALSE(render_client.get()); | 414 EXPECT_FALSE(render_client.Get()); |
| 415 | 415 |
| 416 // Do a proper initialization and verify that it works this time. | 416 // Do a proper initialization and verify that it works this time. |
| 417 CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 417 CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 418 &endpoint_buffer_size, NULL); | 418 &endpoint_buffer_size, NULL); |
| 419 render_client = CoreAudioUtil::CreateRenderClient(client.get()); | 419 render_client = CoreAudioUtil::CreateRenderClient(client.Get()); |
| 420 EXPECT_TRUE(render_client.get()); | 420 EXPECT_TRUE(render_client.Get()); |
| 421 EXPECT_GT(endpoint_buffer_size, 0u); | 421 EXPECT_GT(endpoint_buffer_size, 0u); |
| 422 } else if (data[i] == eCapture) { | 422 } else if (data[i] == eCapture) { |
| 423 // It is not possible to create a capture client using an unitialized | 423 // It is not possible to create a capture client using an unitialized |
| 424 // client interface. | 424 // client interface. |
| 425 capture_client = CoreAudioUtil::CreateCaptureClient(client.get()); | 425 capture_client = CoreAudioUtil::CreateCaptureClient(client.Get()); |
| 426 EXPECT_FALSE(capture_client.get()); | 426 EXPECT_FALSE(capture_client.Get()); |
| 427 | 427 |
| 428 // Do a proper initialization and verify that it works this time. | 428 // Do a proper initialization and verify that it works this time. |
| 429 CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 429 CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 430 &endpoint_buffer_size, NULL); | 430 &endpoint_buffer_size, NULL); |
| 431 capture_client = CoreAudioUtil::CreateCaptureClient(client.get()); | 431 capture_client = CoreAudioUtil::CreateCaptureClient(client.Get()); |
| 432 EXPECT_TRUE(capture_client.get()); | 432 EXPECT_TRUE(capture_client.Get()); |
| 433 EXPECT_GT(endpoint_buffer_size, 0u); | 433 EXPECT_GT(endpoint_buffer_size, 0u); |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 TEST_F(CoreAudioUtilWinTest, FillRenderEndpointBufferWithSilence) { | 438 TEST_F(CoreAudioUtilWinTest, FillRenderEndpointBufferWithSilence) { |
| 439 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 439 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 440 | 440 |
| 441 // Create default clients using the default mixing format for shared mode. | 441 // Create default clients using the default mixing format for shared mode. |
| 442 ScopedComPtr<IAudioClient> client( | 442 ScopedComPtr<IAudioClient> client( |
| 443 CoreAudioUtil::CreateDefaultClient(eRender, eConsole)); | 443 CoreAudioUtil::CreateDefaultClient(eRender, eConsole)); |
| 444 EXPECT_TRUE(client.get()); | 444 EXPECT_TRUE(client.Get()); |
| 445 | 445 |
| 446 WAVEFORMATPCMEX format; | 446 WAVEFORMATPCMEX format; |
| 447 uint32_t endpoint_buffer_size = 0; | 447 uint32_t endpoint_buffer_size = 0; |
| 448 EXPECT_TRUE( | 448 EXPECT_TRUE( |
| 449 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.get(), &format))); | 449 SUCCEEDED(CoreAudioUtil::GetSharedModeMixFormat(client.Get(), &format))); |
| 450 CoreAudioUtil::SharedModeInitialize(client.get(), &format, NULL, | 450 CoreAudioUtil::SharedModeInitialize(client.Get(), &format, NULL, |
| 451 &endpoint_buffer_size, NULL); | 451 &endpoint_buffer_size, NULL); |
| 452 EXPECT_GT(endpoint_buffer_size, 0u); | 452 EXPECT_GT(endpoint_buffer_size, 0u); |
| 453 | 453 |
| 454 ScopedComPtr<IAudioRenderClient> render_client( | 454 ScopedComPtr<IAudioRenderClient> render_client( |
| 455 CoreAudioUtil::CreateRenderClient(client.get())); | 455 CoreAudioUtil::CreateRenderClient(client.Get())); |
| 456 EXPECT_TRUE(render_client.get()); | 456 EXPECT_TRUE(render_client.Get()); |
| 457 | 457 |
| 458 // The endpoint audio buffer should not be filled up by default after being | 458 // The endpoint audio buffer should not be filled up by default after being |
| 459 // created. | 459 // created. |
| 460 UINT32 num_queued_frames = 0; | 460 UINT32 num_queued_frames = 0; |
| 461 client->GetCurrentPadding(&num_queued_frames); | 461 client->GetCurrentPadding(&num_queued_frames); |
| 462 EXPECT_EQ(num_queued_frames, 0u); | 462 EXPECT_EQ(num_queued_frames, 0u); |
| 463 | 463 |
| 464 // Fill it up with zeros and verify that the buffer is full. | 464 // Fill it up with zeros and verify that the buffer is full. |
| 465 // It is not possible to verify that the actual data consists of zeros | 465 // It is not possible to verify that the actual data consists of zeros |
| 466 // since we can't access data that has already been sent to the endpoint | 466 // since we can't access data that has already been sent to the endpoint |
| 467 // buffer. | 467 // buffer. |
| 468 EXPECT_TRUE(CoreAudioUtil::FillRenderEndpointBufferWithSilence( | 468 EXPECT_TRUE(CoreAudioUtil::FillRenderEndpointBufferWithSilence( |
| 469 client.get(), render_client.get())); | 469 client.Get(), render_client.Get())); |
| 470 client->GetCurrentPadding(&num_queued_frames); | 470 client->GetCurrentPadding(&num_queued_frames); |
| 471 EXPECT_EQ(num_queued_frames, endpoint_buffer_size); | 471 EXPECT_EQ(num_queued_frames, endpoint_buffer_size); |
| 472 } | 472 } |
| 473 | 473 |
| 474 // This test can only run on a machine that has audio hardware | 474 // This test can only run on a machine that has audio hardware |
| 475 // that has both input and output devices. | 475 // that has both input and output devices. |
| 476 TEST_F(CoreAudioUtilWinTest, GetMatchingOutputDeviceID) { | 476 TEST_F(CoreAudioUtilWinTest, GetMatchingOutputDeviceID) { |
| 477 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 477 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 478 | 478 |
| 479 bool found_a_pair = false; | 479 bool found_a_pair = false; |
| 480 | 480 |
| 481 ScopedComPtr<IMMDeviceEnumerator> enumerator( | 481 ScopedComPtr<IMMDeviceEnumerator> enumerator( |
| 482 CoreAudioUtil::CreateDeviceEnumerator()); | 482 CoreAudioUtil::CreateDeviceEnumerator()); |
| 483 ASSERT_TRUE(enumerator.get()); | 483 ASSERT_TRUE(enumerator.Get()); |
| 484 | 484 |
| 485 // Enumerate all active input and output devices and fetch the ID of | 485 // Enumerate all active input and output devices and fetch the ID of |
| 486 // the associated device. | 486 // the associated device. |
| 487 ScopedComPtr<IMMDeviceCollection> collection; | 487 ScopedComPtr<IMMDeviceCollection> collection; |
| 488 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(eCapture, | 488 ASSERT_TRUE(SUCCEEDED(enumerator->EnumAudioEndpoints(eCapture, |
| 489 DEVICE_STATE_ACTIVE, collection.Receive()))); | 489 DEVICE_STATE_ACTIVE, collection.Receive()))); |
| 490 UINT count = 0; | 490 UINT count = 0; |
| 491 collection->GetCount(&count); | 491 collection->GetCount(&count); |
| 492 for (UINT i = 0; i < count && !found_a_pair; ++i) { | 492 for (UINT i = 0; i < count && !found_a_pair; ++i) { |
| 493 ScopedComPtr<IMMDevice> device; | 493 ScopedComPtr<IMMDevice> device; |
| 494 collection->Item(i, device.Receive()); | 494 collection->Item(i, device.Receive()); |
| 495 base::win::ScopedCoMem<WCHAR> wide_id; | 495 base::win::ScopedCoMem<WCHAR> wide_id; |
| 496 device->GetId(&wide_id); | 496 device->GetId(&wide_id); |
| 497 std::string id; | 497 std::string id; |
| 498 base::WideToUTF8(wide_id, wcslen(wide_id), &id); | 498 base::WideToUTF8(wide_id, wcslen(wide_id), &id); |
| 499 found_a_pair = !CoreAudioUtil::GetMatchingOutputDeviceID(id).empty(); | 499 found_a_pair = !CoreAudioUtil::GetMatchingOutputDeviceID(id).empty(); |
| 500 } | 500 } |
| 501 | 501 |
| 502 EXPECT_TRUE(found_a_pair); | 502 EXPECT_TRUE(found_a_pair); |
| 503 } | 503 } |
| 504 | 504 |
| 505 TEST_F(CoreAudioUtilWinTest, GetDefaultOutputDeviceID) { | 505 TEST_F(CoreAudioUtilWinTest, GetDefaultOutputDeviceID) { |
| 506 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); | 506 ABORT_AUDIO_TEST_IF_NOT(DevicesAvailable()); |
| 507 | 507 |
| 508 std::string default_device_id(CoreAudioUtil::GetDefaultOutputDeviceID()); | 508 std::string default_device_id(CoreAudioUtil::GetDefaultOutputDeviceID()); |
| 509 EXPECT_FALSE(default_device_id.empty()); | 509 EXPECT_FALSE(default_device_id.empty()); |
| 510 } | 510 } |
| 511 | 511 |
| 512 } // namespace media | 512 } // namespace media |
| OLD | NEW |