| 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/wavein_input_win.h" | 5 #include "media/audio/win/wavein_input_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | |
| 8 #include <mmsystem.h> | |
| 9 #pragma comment(lib, "winmm.lib") | 7 #pragma comment(lib, "winmm.lib") |
| 10 | 8 |
| 11 #include "base/logging.h" | 9 #include "base/logging.h" |
| 12 #include "media/audio/audio_io.h" | 10 #include "media/audio/audio_io.h" |
| 13 #include "media/audio/audio_util.h" | 11 #include "media/audio/audio_util.h" |
| 14 #include "media/audio/win/audio_manager_win.h" | 12 #include "media/audio/win/audio_manager_win.h" |
| 15 #include "media/audio/win/device_enumeration_win.h" | 13 #include "media/audio/win/device_enumeration_win.h" |
| 16 | 14 |
| 17 namespace { | 15 namespace { |
| 18 const int kStopInputStreamCallbackTimeout = 3000; // Three seconds. | 16 const int kStopInputStreamCallbackTimeout = 3000; // Three seconds. |
| 19 } | 17 } |
| 20 | 18 |
| 21 using media::AudioDeviceNames; | 19 using media::AudioDeviceNames; |
| 22 | 20 |
| 23 // Our sound buffers are allocated once and kept in a linked list using the | 21 // Our sound buffers are allocated once and kept in a linked list using the |
| 24 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer. | 22 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer. |
| 25 static WAVEHDR* GetNextBuffer(WAVEHDR* current) { | 23 static WAVEHDR* GetNextBuffer(WAVEHDR* current) { |
| 26 return reinterpret_cast<WAVEHDR*>(current->dwUser); | 24 return reinterpret_cast<WAVEHDR*>(current->dwUser); |
| 27 } | 25 } |
| 28 | 26 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 192 |
| 195 void PCMWaveInAudioInputStream::SetVolume(double volume) { | 193 void PCMWaveInAudioInputStream::SetVolume(double volume) { |
| 196 // TODO(henrika): Add volume support using the Audio Mixer API. | 194 // TODO(henrika): Add volume support using the Audio Mixer API. |
| 197 } | 195 } |
| 198 | 196 |
| 199 double PCMWaveInAudioInputStream::GetVolume() { | 197 double PCMWaveInAudioInputStream::GetVolume() { |
| 200 // TODO(henrika): Add volume support using the Audio Mixer API. | 198 // TODO(henrika): Add volume support using the Audio Mixer API. |
| 201 return 0.0; | 199 return 0.0; |
| 202 } | 200 } |
| 203 | 201 |
| 202 void PCMWaveInAudioInputStream::SetAutomaticGainControl(bool enabled) { |
| 203 // TODO(henrika): Add AGC support when volume control has been added. |
| 204 NOTIMPLEMENTED(); |
| 205 } |
| 206 |
| 207 bool PCMWaveInAudioInputStream::GetAutomaticGainControl() { |
| 208 // TODO(henrika): Add AGC support when volume control has been added. |
| 209 NOTIMPLEMENTED(); |
| 210 return false; |
| 211 } |
| 212 |
| 204 void PCMWaveInAudioInputStream::HandleError(MMRESULT error) { | 213 void PCMWaveInAudioInputStream::HandleError(MMRESULT error) { |
| 205 DLOG(WARNING) << "PCMWaveInAudio error " << error; | 214 DLOG(WARNING) << "PCMWaveInAudio error " << error; |
| 206 callback_->OnError(this, error); | 215 callback_->OnError(this, error); |
| 207 } | 216 } |
| 208 | 217 |
| 209 void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) { | 218 void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) { |
| 210 MMRESULT res = ::waveInAddBuffer(wavein_, buffer, sizeof(WAVEHDR)); | 219 MMRESULT res = ::waveInAddBuffer(wavein_, buffer, sizeof(WAVEHDR)); |
| 211 if (res != MMSYSERR_NOERROR) | 220 if (res != MMSYSERR_NOERROR) |
| 212 HandleError(res); | 221 HandleError(res); |
| 213 } | 222 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 DWORD_PTR instance, | 262 DWORD_PTR instance, |
| 254 DWORD_PTR param1, DWORD_PTR) { | 263 DWORD_PTR param1, DWORD_PTR) { |
| 255 PCMWaveInAudioInputStream* obj = | 264 PCMWaveInAudioInputStream* obj = |
| 256 reinterpret_cast<PCMWaveInAudioInputStream*>(instance); | 265 reinterpret_cast<PCMWaveInAudioInputStream*>(instance); |
| 257 | 266 |
| 258 if (msg == WIM_DATA) { | 267 if (msg == WIM_DATA) { |
| 259 // WIM_DONE indicates that the driver is done with our buffer. We pass it | 268 // WIM_DONE indicates that the driver is done with our buffer. We pass it |
| 260 // to the callback and check if we need to stop playing. | 269 // to the callback and check if we need to stop playing. |
| 261 // It should be OK to assume the data in the buffer is what has been | 270 // It should be OK to assume the data in the buffer is what has been |
| 262 // recorded in the soundcard. | 271 // recorded in the soundcard. |
| 272 // TODO(henrika): the |volume| parameter is always set to zero since there |
| 273 // is currently no support for controlling the microphone volume level. |
| 263 WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1); | 274 WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1); |
| 264 obj->callback_->OnData(obj, reinterpret_cast<const uint8*>(buffer->lpData), | 275 obj->callback_->OnData(obj, reinterpret_cast<const uint8*>(buffer->lpData), |
| 265 buffer->dwBytesRecorded, | 276 buffer->dwBytesRecorded, |
| 266 buffer->dwBytesRecorded); | 277 buffer->dwBytesRecorded, |
| 278 0.0); |
| 267 | 279 |
| 268 if (obj->state_ == kStateStopping) { | 280 if (obj->state_ == kStateStopping) { |
| 269 // The main thread has called Stop() and is waiting to issue waveOutReset | 281 // The main thread has called Stop() and is waiting to issue waveOutReset |
| 270 // which will kill this thread. We should not enter AudioSourceCallback | 282 // which will kill this thread. We should not enter AudioSourceCallback |
| 271 // code anymore. | 283 // code anymore. |
| 272 ::SetEvent(obj->stopped_event_); | 284 ::SetEvent(obj->stopped_event_); |
| 273 } else if (obj->state_ == kStateStopped) { | 285 } else if (obj->state_ == kStateStopped) { |
| 274 // Not sure if ever hit this but just in case. | 286 // Not sure if ever hit this but just in case. |
| 275 } else { | 287 } else { |
| 276 // Queue the finished buffer back with the audio driver. Since we are | 288 // Queue the finished buffer back with the audio driver. Since we are |
| 277 // reusing the same buffers we can get away without calling | 289 // reusing the same buffers we can get away without calling |
| 278 // waveInPrepareHeader. | 290 // waveInPrepareHeader. |
| 279 obj->QueueNextPacket(buffer); | 291 obj->QueueNextPacket(buffer); |
| 280 } | 292 } |
| 281 } else if (msg == WIM_CLOSE) { | 293 } else if (msg == WIM_CLOSE) { |
| 282 // We can be closed before calling Start, so it is possible to have a | 294 // We can be closed before calling Start, so it is possible to have a |
| 283 // null callback at this point. | 295 // null callback at this point. |
| 284 if (obj->callback_) | 296 if (obj->callback_) |
| 285 obj->callback_->OnClose(obj); | 297 obj->callback_->OnClose(obj); |
| 286 } | 298 } |
| 287 } | 299 } |
| OLD | NEW |