| 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/audio_io.h" | 5 #include "media/audio/audio_io.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <objbase.h> // This has to be before initguid.h | 8 #include <objbase.h> // This has to be before initguid.h |
| 9 #include <initguid.h> | 9 #include <initguid.h> |
| 10 #include <mmsystem.h> | 10 #include <mmsystem.h> |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 // Use 4 buffers for Vista, 3 for everyone else: | 121 // Use 4 buffers for Vista, 3 for everyone else: |
| 122 // - The entire Windows audio stack was rewritten for Windows Vista and wave | 122 // - The entire Windows audio stack was rewritten for Windows Vista and wave |
| 123 // out performance was degraded compared to XP. | 123 // out performance was degraded compared to XP. |
| 124 // - The regression was fixed in Windows 7 and most configurations will work | 124 // - The regression was fixed in Windows 7 and most configurations will work |
| 125 // with 2, but some (e.g., some Sound Blasters) still need 3. | 125 // with 2, but some (e.g., some Sound Blasters) still need 3. |
| 126 // - Some XP configurations (even multi-processor ones) also need 3. | 126 // - Some XP configurations (even multi-processor ones) also need 3. |
| 127 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; | 127 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; |
| 128 } | 128 } |
| 129 | 129 |
| 130 AudioManagerWin::AudioManagerWin(AudioLogFactory* audio_log_factory) | 130 AudioManagerWin::AudioManagerWin(AudioLogFactory* audio_log_factory) |
| 131 : AudioManagerBase(audio_log_factory) { | 131 : AudioManagerBase(audio_log_factory), |
| 132 if (!CoreAudioUtil::IsSupported()) { | 132 enumeration_type_(kUninitializedEnumeration) { |
| 133 // Use the Wave API for device enumeration if XP or lower. | 133 SetMaxOutputStreamsAllowed(kMaxOutputStreams); |
| 134 enumeration_type_ = kWaveEnumeration; | |
| 135 } else { | |
| 136 // Use the MMDevice API for device enumeration if Vista or higher. | |
| 137 enumeration_type_ = kMMDeviceEnumeration; | |
| 138 } | |
| 139 | 134 |
| 140 SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 135 // WARNING: This is executed on the UI loop, do not add any code here which |
| 136 // loads libraries or attempts to call out into the OS. Instead add such code |
| 137 // to the InitializeOnAudioThread() method below. |
| 141 | 138 |
| 142 // Task must be posted last to avoid races from handing out "this" to the | 139 // Task must be posted last to avoid races from handing out "this" to the |
| 143 // audio thread. | 140 // audio thread. |
| 144 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( | 141 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( |
| 145 &AudioManagerWin::CreateDeviceListener, base::Unretained(this))); | 142 &AudioManagerWin::InitializeOnAudioThread, base::Unretained(this))); |
| 146 } | 143 } |
| 147 | 144 |
| 148 AudioManagerWin::~AudioManagerWin() { | 145 AudioManagerWin::~AudioManagerWin() { |
| 149 // It's safe to post a task here since Shutdown() will wait for all tasks to | 146 // It's safe to post a task here since Shutdown() will wait for all tasks to |
| 150 // complete before returning. | 147 // complete before returning. |
| 151 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( | 148 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( |
| 152 &AudioManagerWin::DestroyDeviceListener, base::Unretained(this))); | 149 &AudioManagerWin::ShutdownOnAudioThread, base::Unretained(this))); |
| 153 Shutdown(); | 150 Shutdown(); |
| 154 } | 151 } |
| 155 | 152 |
| 156 bool AudioManagerWin::HasAudioOutputDevices() { | 153 bool AudioManagerWin::HasAudioOutputDevices() { |
| 157 return (::waveOutGetNumDevs() != 0); | 154 return (::waveOutGetNumDevs() != 0); |
| 158 } | 155 } |
| 159 | 156 |
| 160 bool AudioManagerWin::HasAudioInputDevices() { | 157 bool AudioManagerWin::HasAudioInputDevices() { |
| 161 return (::waveInGetNumDevs() != 0); | 158 return (::waveInGetNumDevs() != 0); |
| 162 } | 159 } |
| 163 | 160 |
| 164 void AudioManagerWin::CreateDeviceListener() { | 161 void AudioManagerWin::InitializeOnAudioThread() { |
| 165 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 162 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 166 | 163 |
| 167 // AudioDeviceListenerWin must be initialized on a COM thread and should only | |
| 168 // be used if WASAPI / Core Audio is supported. | |
| 169 if (CoreAudioUtil::IsSupported()) { | 164 if (CoreAudioUtil::IsSupported()) { |
| 165 // Use the MMDevice API for device enumeration if Vista or higher. |
| 166 enumeration_type_ = kMMDeviceEnumeration; |
| 167 |
| 168 // AudioDeviceListenerWin must be initialized on a COM thread and should |
| 169 // only be used if WASAPI / Core Audio is supported. |
| 170 output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop( | 170 output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop( |
| 171 base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners, | 171 base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners, |
| 172 base::Unretained(this))))); | 172 base::Unretained(this))))); |
| 173 } else { |
| 174 // Use the Wave API for device enumeration if XP or lower. |
| 175 enumeration_type_ = kWaveEnumeration; |
| 173 } | 176 } |
| 174 } | 177 } |
| 175 | 178 |
| 176 void AudioManagerWin::DestroyDeviceListener() { | 179 void AudioManagerWin::ShutdownOnAudioThread() { |
| 177 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 180 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 178 output_device_listener_.reset(); | 181 output_device_listener_.reset(); |
| 179 } | 182 } |
| 180 | 183 |
| 181 base::string16 AudioManagerWin::GetAudioInputDeviceModel() { | 184 base::string16 AudioManagerWin::GetAudioInputDeviceModel() { |
| 182 // Get the default audio capture device and its device interface name. | 185 // Get the default audio capture device and its device interface name. |
| 183 DWORD device_id = 0; | 186 DWORD device_id = 0; |
| 184 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER), | 187 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER), |
| 185 DRVM_MAPPER_PREFERRED_GET, | 188 DRVM_MAPPER_PREFERRED_GET, |
| 186 reinterpret_cast<DWORD_PTR>(&device_id), NULL); | 189 reinterpret_cast<DWORD_PTR>(&device_id), NULL); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, | 528 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, |
| 526 xp_device_id); | 529 xp_device_id); |
| 527 } | 530 } |
| 528 | 531 |
| 529 /// static | 532 /// static |
| 530 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { | 533 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { |
| 531 return new AudioManagerWin(audio_log_factory); | 534 return new AudioManagerWin(audio_log_factory); |
| 532 } | 535 } |
| 533 | 536 |
| 534 } // namespace media | 537 } // namespace media |
| OLD | NEW |