Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: media/audio/win/audio_manager_win.cc

Issue 9570014: Move some generic functions to AudioManagerBase to be inherited by platform-specific AudioManager*** (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased and fixed windows compiling Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/win/audio_manager_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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>
11 #include <setupapi.h> 11 #include <setupapi.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
17 #include "base/path_service.h" 17 #include "base/path_service.h"
18 #include "base/process_util.h" 18 #include "base/process_util.h"
19 #include "base/string_number_conversions.h" 19 #include "base/string_number_conversions.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "media/audio/audio_util.h" 21 #include "media/audio/audio_util.h"
22 #include "media/audio/fake_audio_input_stream.h"
23 #include "media/audio/fake_audio_output_stream.h"
24 #include "media/audio/win/audio_low_latency_input_win.h" 22 #include "media/audio/win/audio_low_latency_input_win.h"
25 #include "media/audio/win/audio_low_latency_output_win.h" 23 #include "media/audio/win/audio_low_latency_output_win.h"
26 #include "media/audio/win/audio_manager_win.h" 24 #include "media/audio/win/audio_manager_win.h"
27 #include "media/audio/win/device_enumeration_win.h" 25 #include "media/audio/win/device_enumeration_win.h"
28 #include "media/audio/win/wavein_input_win.h" 26 #include "media/audio/win/wavein_input_win.h"
29 #include "media/audio/win/waveout_output_win.h" 27 #include "media/audio/win/waveout_output_win.h"
30 #include "media/base/limits.h" 28 #include "media/base/limits.h"
31 29
32 // Libraries required for the SetupAPI and Wbem APIs used here. 30 // Libraries required for the SetupAPI and Wbem APIs used here.
33 #pragma comment(lib, "setupapi.lib") 31 #pragma comment(lib, "setupapi.lib")
34 32
35 // The following are defined in various DDK headers, and we (re)define them 33 // The following are defined in various DDK headers, and we (re)define them
36 // here to avoid adding the DDK as a chrome dependency. 34 // here to avoid adding the DDK as a chrome dependency.
37 #define DRV_QUERYDEVICEINTERFACE 0x80c 35 #define DRV_QUERYDEVICEINTERFACE 0x80c
38 #define DRVM_MAPPER_PREFERRED_GET 0x2015 36 #define DRVM_MAPPER_PREFERRED_GET 0x2015
39 #define DRV_QUERYDEVICEINTERFACESIZE 0x80d 37 #define DRV_QUERYDEVICEINTERFACESIZE 0x80d
40 DEFINE_GUID(AM_KSCATEGORY_AUDIO, 0x6994ad04, 0x93ef, 0x11d0, 38 DEFINE_GUID(AM_KSCATEGORY_AUDIO, 0x6994ad04, 0x93ef, 0x11d0,
41 0xa3, 0xcc, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96); 39 0xa3, 0xcc, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96);
42 40
43 // Maximum number of output streams that can be open simultaneously. 41 // Maximum number of output streams that can be open simultaneously.
44 static const size_t kMaxOutputStreams = 50; 42 static const int kMaxOutputStreams = 50;
45 43
46 // Up to 8 channels can be passed to the driver. 44 // Up to 8 channels can be passed to the driver.
47 // This should work, given the right drivers, but graceful error handling is 45 // This should work, given the right drivers, but graceful error handling is
48 // needed. 46 // needed.
49 static const int kWinMaxChannels = 8; 47 static const int kWinMaxChannels = 8;
50 48
51 static const int kWinMaxInputChannels = 2;
52 // We use 3 buffers for recording audio so that if a recording callback takes 49 // We use 3 buffers for recording audio so that if a recording callback takes
53 // some time to return we won't lose audio. More buffers while recording are 50 // some time to return we won't lose audio. More buffers while recording are
54 // ok because they don't introduce any delay in recording, unlike in playback 51 // ok because they don't introduce any delay in recording, unlike in playback
55 // where you first need to fill in that number of buffers before starting to 52 // where you first need to fill in that number of buffers before starting to
56 // play. 53 // play.
57 static const int kNumInputBuffers = 3; 54 static const int kNumInputBuffers = 3;
58 55
59 static int GetVersionPartAsInt(DWORDLONG num) { 56 static int GetVersionPartAsInt(DWORDLONG num) {
60 return static_cast<int>(num & 0xffff); 57 return static_cast<int>(num & 0xffff);
61 } 58 }
(...skipping 29 matching lines...) Expand all
91 } 88 }
92 SetupDiDestroyDriverInfoList(device_info, device_data, SPDIT_COMPATDRIVER); 89 SetupDiDestroyDriverInfoList(device_info, device_data, SPDIT_COMPATDRIVER);
93 } 90 }
94 91
95 SetupDiSetDeviceInstallParams(device_info, device_data, 92 SetupDiSetDeviceInstallParams(device_info, device_data,
96 &old_device_install_params); 93 &old_device_install_params);
97 94
98 return device_and_driver_info; 95 return device_and_driver_info;
99 } 96 }
100 97
101 AudioManagerWin::AudioManagerWin() 98 AudioManagerWin::AudioManagerWin() {
102 : num_output_streams_(0) {
103 if (!media::IsWASAPISupported()) { 99 if (!media::IsWASAPISupported()) {
104 // Use the Wave API for device enumeration if XP or lower. 100 // Use the Wave API for device enumeration if XP or lower.
105 enumeration_type_ = kWaveEnumeration; 101 enumeration_type_ = kWaveEnumeration;
106 } else { 102 } else {
107 // Use the MMDevice API for device enumeration if Vista or higher. 103 // Use the MMDevice API for device enumeration if Vista or higher.
108 enumeration_type_ = kMMDeviceEnumeration; 104 enumeration_type_ = kMMDeviceEnumeration;
109 } 105 }
106
107 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
110 } 108 }
111 109
112 AudioManagerWin::~AudioManagerWin() { 110 AudioManagerWin::~AudioManagerWin() {
113 // All output streams should be released upon termination.
114 DCHECK_EQ(0, num_output_streams_);
115 } 111 }
116 112
117 bool AudioManagerWin::HasAudioOutputDevices() { 113 bool AudioManagerWin::HasAudioOutputDevices() {
118 return (::waveOutGetNumDevs() != 0); 114 return (::waveOutGetNumDevs() != 0);
119 } 115 }
120 116
121 bool AudioManagerWin::HasAudioInputDevices() { 117 bool AudioManagerWin::HasAudioInputDevices() {
122 return (::waveInGetNumDevs() != 0); 118 return (::waveInGetNumDevs() != 0);
123 } 119 }
124 120
125 // Factory for the implementations of AudioOutputStream. Two implementations
126 // should suffice most windows user's needs.
127 // - PCMWaveOutAudioOutputStream: Based on the waveOut API.
128 // - WASAPIAudioOutputStream: Based on Core Audio (WASAPI) API.
129 AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
130 const AudioParameters& params) {
131 if (!params.IsValid() || (params.channels > kWinMaxChannels))
132 return NULL;
133
134 // Limit the number of audio streams opened.
135 if (num_output_streams_ >= kMaxOutputStreams) {
136 return NULL;
137 }
138
139 if (params.format == AudioParameters::AUDIO_MOCK) {
140 return FakeAudioOutputStream::MakeFakeStream(params);
141 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
142 num_output_streams_++;
143 return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER);
144 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
145 num_output_streams_++;
146 if (!media::IsWASAPISupported()) {
147 // Fall back to Windows Wave implementation on Windows XP or lower.
148 DLOG(INFO) << "Using WaveOut since WASAPI requires at least Vista.";
149 return new PCMWaveOutAudioOutputStream(this, params, 2, WAVE_MAPPER);
150 } else {
151 // TODO(henrika): improve possibility to specify audio endpoint.
152 // Use the default device (same as for Wave) for now to be compatible.
153 return new WASAPIAudioOutputStream(this, params, eConsole);
154 }
155 }
156 return NULL;
157 }
158
159 // Factory for the implementations of AudioInputStream.
160 AudioInputStream* AudioManagerWin::MakeAudioInputStream(
161 const AudioParameters& params, const std::string& device_id) {
162 if (!params.IsValid() || (params.channels > kWinMaxInputChannels) ||
163 device_id.empty())
164 return NULL;
165
166 if (params.format == AudioParameters::AUDIO_MOCK) {
167 return FakeAudioInputStream::MakeFakeStream(params);
168 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
169 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
170 AudioManagerBase::kDefaultDeviceId);
171 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
172 if (!media::IsWASAPISupported()) {
173 // Fall back to Windows Wave implementation on Windows XP or lower.
174 DLOG(INFO) << "Using WaveIn since WASAPI requires at least Vista.";
175 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
176 device_id);
177 } else {
178 return new WASAPIAudioInputStream(this, params, device_id);
179 }
180 }
181 return NULL;
182 }
183
184 void AudioManagerWin::ReleaseOutputStream(AudioOutputStream* stream) {
185 DCHECK(stream);
186 num_output_streams_--;
187 delete stream;
188 }
189
190 void AudioManagerWin::ReleaseInputStream(AudioInputStream* stream) {
191 delete stream;
192 }
193
194 void AudioManagerWin::MuteAll() { 121 void AudioManagerWin::MuteAll() {
195 } 122 }
196 123
197 void AudioManagerWin::UnMuteAll() { 124 void AudioManagerWin::UnMuteAll() {
198 } 125 }
199 126
200 string16 AudioManagerWin::GetAudioInputDeviceModel() { 127 string16 AudioManagerWin::GetAudioInputDeviceModel() {
201 // Get the default audio capture device and its device interface name. 128 // Get the default audio capture device and its device interface name.
202 DWORD device_id = 0; 129 DWORD device_id = 0;
203 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER), 130 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER),
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 225
299 // Always add default device parameters as first element. 226 // Always add default device parameters as first element.
300 if (!device_names->empty()) { 227 if (!device_names->empty()) {
301 media::AudioDeviceName name; 228 media::AudioDeviceName name;
302 name.device_name = AudioManagerBase::kDefaultDeviceName; 229 name.device_name = AudioManagerBase::kDefaultDeviceName;
303 name.unique_id = AudioManagerBase::kDefaultDeviceId; 230 name.unique_id = AudioManagerBase::kDefaultDeviceId;
304 device_names->push_front(name); 231 device_names->push_front(name);
305 } 232 }
306 } 233 }
307 234
235 // Factory for the implementations of AudioOutputStream for AUDIO_PCM_LINEAR
236 // mode.
237 // - PCMWaveOutAudioOutputStream: Based on the waveOut API.
238 AudioOutputStream* AudioManagerWin::MakeLinearOutputStream(
239 const AudioParameters& params) {
240 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
241 if (params.channels > kWinMaxChannels)
242 return NULL;
243
244 return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER);
245 }
246
247 // Factory for the implementations of AudioOutputStream for
248 // AUDIO_PCM_LOW_LATENCY mode. Two implementations should suffice most
249 // windows user's needs.
250 // - PCMWaveOutAudioOutputStream: Based on the waveOut API.
251 // - WASAPIAudioOutputStream: Based on Core Audio (WASAPI) API.
252 AudioOutputStream* AudioManagerWin::MakeLowLatencyOutputStream(
253 const AudioParameters& params) {
254 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
255 if (params.channels > kWinMaxChannels)
256 return NULL;
257
258 AudioOutputStream* stream = NULL;
259 if (!media::IsWASAPISupported()) {
260 // Fall back to Windows Wave implementation on Windows XP or lower.
261 DVLOG(1) << "Using WaveOut since WASAPI requires at least Vista.";
262 stream = new PCMWaveOutAudioOutputStream(this, params, 2, WAVE_MAPPER);
263 } else {
264 // TODO(henrika): improve possibility to specify audio endpoint.
265 // Use the default device (same as for Wave) for now to be compatible.
266 stream = new WASAPIAudioOutputStream(this, params, eConsole);
267 }
268
269 return stream;
270 }
271
272 // Factory for the implementations of AudioInputStream for AUDIO_PCM_LINEAR
273 // mode.
274 AudioInputStream* AudioManagerWin::MakeLinearInputStream(
275 const AudioParameters& params, const std::string& device_id) {
276 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
277 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
278 AudioManagerBase::kDefaultDeviceId);
279 }
280
281 // Factory for the implementations of AudioInputStream for
282 // AUDIO_PCM_LOW_LATENCY mode.
283 AudioInputStream* AudioManagerWin::MakeLowLatencyInputStream(
284 const AudioParameters& params, const std::string& device_id) {
285 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
286 AudioInputStream* stream = NULL;
287 if (!media::IsWASAPISupported()) {
288 // Fall back to Windows Wave implementation on Windows XP or lower.
289 DVLOG(1) << "Using WaveIn since WASAPI requires at least Vista.";
290 stream = new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
291 device_id);
292 } else {
293 stream = new WASAPIAudioInputStream(this, params, device_id);
294 }
295
296 return stream;
297 }
298
308 /// static 299 /// static
309 AudioManager* CreateAudioManager() { 300 AudioManager* CreateAudioManager() {
310 return new AudioManagerWin(); 301 return new AudioManagerWin();
311 } 302 }
OLDNEW
« no previous file with comments | « media/audio/win/audio_manager_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698