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

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

Issue 8770005: Adds input device selection on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years 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
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/win/wavein_input_win.h" 5 #include "media/audio/win/wavein_input_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <mmsystem.h> 8 #include <mmsystem.h>
9 #pragma comment(lib, "winmm.lib") 9 #pragma comment(lib, "winmm.lib")
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "media/audio/audio_io.h" 12 #include "media/audio/audio_io.h"
13 #include "media/audio/audio_util.h" 13 #include "media/audio/audio_util.h"
14 #include "media/audio/win/audio_manager_win.h" 14 #include "media/audio/win/audio_manager_win.h"
15 #include "media/audio/win/device_enumeration_win.h"
15 16
16 namespace { 17 namespace {
17 const int kStopInputStreamCallbackTimeout = 3000; // Three seconds. 18 const int kStopInputStreamCallbackTimeout = 3000; // Three seconds.
18 } 19 }
19 20
21 using media::AudioDeviceNames;
22
20 // Our sound buffers are allocated once and kept in a linked list using the 23 // Our sound buffers are allocated once and kept in a linked list using the
21 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer. 24 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer.
22 static WAVEHDR* GetNextBuffer(WAVEHDR* current) { 25 static WAVEHDR* GetNextBuffer(WAVEHDR* current) {
23 return reinterpret_cast<WAVEHDR*>(current->dwUser); 26 return reinterpret_cast<WAVEHDR*>(current->dwUser);
24 } 27 }
25 28
26 PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( 29 PCMWaveInAudioInputStream::PCMWaveInAudioInputStream(
27 AudioManagerWin* manager, const AudioParameters& params, int num_buffers, 30 AudioManagerWin* manager, const AudioParameters& params, int num_buffers,
28 UINT device_id) 31 const std::string& device_id)
29 : state_(kStateEmpty), 32 : state_(kStateEmpty),
30 manager_(manager), 33 manager_(manager),
31 device_id_(device_id), 34 device_id_(device_id),
32 wavein_(NULL), 35 wavein_(NULL),
33 callback_(NULL), 36 callback_(NULL),
34 num_buffers_(num_buffers), 37 num_buffers_(num_buffers),
35 buffer_(NULL), 38 buffer_(NULL),
36 channels_(params.channels) { 39 channels_(params.channels) {
37 format_.wFormatTag = WAVE_FORMAT_PCM; 40 format_.wFormatTag = WAVE_FORMAT_PCM;
38 format_.nChannels = params.channels > 2 ? 2 : params.channels; 41 format_.nChannels = params.channels > 2 ? 2 : params.channels;
(...skipping 12 matching lines...) Expand all
51 54
52 PCMWaveInAudioInputStream::~PCMWaveInAudioInputStream() { 55 PCMWaveInAudioInputStream::~PCMWaveInAudioInputStream() {
53 DCHECK(NULL == wavein_); 56 DCHECK(NULL == wavein_);
54 } 57 }
55 58
56 bool PCMWaveInAudioInputStream::Open() { 59 bool PCMWaveInAudioInputStream::Open() {
57 if (state_ != kStateEmpty) 60 if (state_ != kStateEmpty)
58 return false; 61 return false;
59 if (num_buffers_ < 2 || num_buffers_ > 10) 62 if (num_buffers_ < 2 || num_buffers_ > 10)
60 return false; 63 return false;
61 MMRESULT result = ::waveInOpen(&wavein_, device_id_, &format_, 64
62 reinterpret_cast<DWORD_PTR>(WaveCallback), 65 // Convert the stored device id string into an unsigned integer
63 reinterpret_cast<DWORD_PTR>(this), 66 // corresponding to the selected device.
64 CALLBACK_FUNCTION); 67 UINT device_id = WAVE_MAPPER;
68 if (!GetDeviceId(&device_id)) {
69 return false;
70 }
71
72 // Open the specified input device for recording.
73 MMRESULT result = MMSYSERR_NOERROR;
74 result = ::waveInOpen(&wavein_, device_id, &format_,
75 reinterpret_cast<DWORD_PTR>(WaveCallback),
76 reinterpret_cast<DWORD_PTR>(this),
77 CALLBACK_FUNCTION);
65 if (result != MMSYSERR_NOERROR) 78 if (result != MMSYSERR_NOERROR)
66 return false; 79 return false;
67 80
68 SetupBuffers(); 81 SetupBuffers();
69 state_ = kStateReady; 82 state_ = kStateReady;
70 return true; 83 return true;
71 } 84 }
72 85
73 void PCMWaveInAudioInputStream::SetupBuffers() { 86 void PCMWaveInAudioInputStream::SetupBuffers() {
74 WAVEHDR* last = NULL; 87 WAVEHDR* last = NULL;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 DLOG(WARNING) << "PCMWaveInAudio error " << error; 191 DLOG(WARNING) << "PCMWaveInAudio error " << error;
179 callback_->OnError(this, error); 192 callback_->OnError(this, error);
180 } 193 }
181 194
182 void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) { 195 void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) {
183 MMRESULT res = ::waveInAddBuffer(wavein_, buffer, sizeof(WAVEHDR)); 196 MMRESULT res = ::waveInAddBuffer(wavein_, buffer, sizeof(WAVEHDR));
184 if (res != MMSYSERR_NOERROR) 197 if (res != MMSYSERR_NOERROR)
185 HandleError(res); 198 HandleError(res);
186 } 199 }
187 200
201 bool PCMWaveInAudioInputStream::GetDeviceId(UINT* device_index) {
202 // Deliver the default input device id (WAVE_MAPPER) if the default
203 // device has been selected.
204 if (device_id_ == AudioManagerBase::kDefaultDeviceId) {
205 *device_index = WAVE_MAPPER;
206 return true;
207 }
208
209 // Get list of all available and active devices.
210 AudioDeviceNames device_names;
211 if (!GetInputDeviceNamesWinXP(&device_names)) {
tommi (sloooow) - chröme 2011/12/01 14:11:03 nit: no need for {} (like the the next statement)
henrika (OOO until Aug 14) 2011/12/01 16:02:38 Done.
212 return false;
213 }
214
215 if (device_names.empty())
216 return false;
217
218 // Search the full list of devices and compare with the specified
219 // device id which was specified in the constructor. Stop comparing
220 // when a match is found and return the corresponding index.
221 UINT index = 0;
222 AudioDeviceNames::const_iterator it = device_names.begin();
223 while (it != device_names.end()) {
no longer working on chromium 2011/12/01 15:28:03 what happen if none of the device in the list matc
henrika (OOO until Aug 14) 2011/12/01 16:02:38 Done.
224 if (it->unique_id.compare(device_id_) == 0) {
no longer working on chromium 2011/12/01 15:28:03 we can directly use device_id_ == it->unique_id
henrika (OOO until Aug 14) 2011/12/01 16:02:38 I actually prefer the compare() method for std::st
225 *device_index = index;
226 break;
227 }
228 ++index;
229 ++it;
230 }
231
232 return true;
233 }
234
188 // Windows calls us back in this function when some events happen. Most notably 235 // Windows calls us back in this function when some events happen. Most notably
189 // when it has an audio buffer with recorded data. 236 // when it has an audio buffer with recorded data.
190 void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg, 237 void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg,
191 DWORD_PTR instance, 238 DWORD_PTR instance,
192 DWORD_PTR param1, DWORD_PTR) { 239 DWORD_PTR param1, DWORD_PTR) {
193 PCMWaveInAudioInputStream* obj = 240 PCMWaveInAudioInputStream* obj =
194 reinterpret_cast<PCMWaveInAudioInputStream*>(instance); 241 reinterpret_cast<PCMWaveInAudioInputStream*>(instance);
195 242
196 if (msg == WIM_DATA) { 243 if (msg == WIM_DATA) {
197 // WIM_DONE indicates that the driver is done with our buffer. We pass it 244 // WIM_DONE indicates that the driver is done with our buffer. We pass it
(...skipping 18 matching lines...) Expand all
216 // waveInPrepareHeader. 263 // waveInPrepareHeader.
217 obj->QueueNextPacket(buffer); 264 obj->QueueNextPacket(buffer);
218 } 265 }
219 } else if (msg == WIM_CLOSE) { 266 } else if (msg == WIM_CLOSE) {
220 // We can be closed before calling Start, so it is possible to have a 267 // We can be closed before calling Start, so it is possible to have a
221 // null callback at this point. 268 // null callback at this point.
222 if (obj->callback_) 269 if (obj->callback_)
223 obj->callback_->OnClose(obj); 270 obj->callback_->OnClose(obj);
224 } 271 }
225 } 272 }
OLDNEW
« media/audio/win/audio_low_latency_input_win.cc ('K') | « media/audio/win/wavein_input_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698