diff options
Diffstat (limited to 'media/audio/win')
-rw-r--r-- | media/audio/win/audio_low_latency_input_win.cc | 26 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_input_win.h | 4 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_input_win_unittest.cc | 14 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_output_win.cc | 2 | ||||
-rw-r--r-- | media/audio/win/wavein_input_win.cc | 20 | ||||
-rw-r--r-- | media/audio/win/wavein_input_win.h | 4 |
6 files changed, 53 insertions, 17 deletions
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc index 8344aba..214b8bf9 100644 --- a/media/audio/win/audio_low_latency_input_win.cc +++ b/media/audio/win/audio_low_latency_input_win.cc @@ -192,8 +192,10 @@ double WASAPIAudioInputStream::GetMaxVolume() { } void WASAPIAudioInputStream::SetVolume(double volume) { + DVLOG(1) << "SetVolume(volume=" << volume << ")"; DCHECK(CalledOnValidThread()); - DCHECK(volume <= 1.0 && volume >= 0.0); + DCHECK_GE(volume, 0.0); + DCHECK_LE(volume, 1.0); DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; if (!opened_) @@ -202,12 +204,18 @@ void WASAPIAudioInputStream::SetVolume(double volume) { // Set a new master volume level. Valid volume levels are in the range // 0.0 to 1.0. Ignore volume-change events. HRESULT hr = simple_audio_volume_->SetMasterVolume(static_cast<float>(volume), - NULL); + NULL); DLOG_IF(WARNING, FAILED(hr)) << "Failed to set new input master volume."; + + // Update the AGC volume level based on the last setting above. Note that, + // the volume-level resolution is not infinite and it is therefore not + // possible to assume that the volume provided as input parameter can be + // used directly. Instead, a new query to the audio hardware is required. + // This method does nothing if AGC is disabled. + UpdateAgcVolume(); } double WASAPIAudioInputStream::GetVolume() { - DCHECK(CalledOnValidThread()); DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; if (!opened_) return 0.0; @@ -323,6 +331,7 @@ void WASAPIAudioInputStream::Run() { LARGE_INTEGER now_count; bool recording = true; bool error = false; + double volume = GetVolume(); HANDLE wait_array[2] = {stop_capture_event_, audio_samples_ready_event_}; while (recording && !error) { @@ -389,6 +398,11 @@ void WASAPIAudioInputStream::Run() { first_audio_frame_timestamp) / 10000.0) * ms_to_frame_count_ + buffer_frame_index - num_frames_to_read; + // Update the AGC volume level once every second. Note that, + // |volume| is also updated each time SetVolume() is called + // through IPC by the render-side AGC. + QueryAgcVolume(&volume); + // Deliver captured data to the registered consumer using a packet // size which was specified at construction. uint32 delay_frames = static_cast<uint32>(audio_delay_frames + 0.5); @@ -396,11 +410,13 @@ void WASAPIAudioInputStream::Run() { uint8* audio_data = reinterpret_cast<uint8*>(capture_buffer.get()); - // Deliver data packet and delay estimation to the user. + // Deliver data packet, delay estimation and volume level to + // the user. sink_->OnData(this, audio_data, packet_size_bytes_, - delay_frames * frame_size_); + delay_frames * frame_size_, + volume); // Store parts of the recorded data which can't be delivered // using the current packet size. The stored section will be used diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h index 276a342..d546829 100644 --- a/media/audio/win/audio_low_latency_input_win.h +++ b/media/audio/win/audio_low_latency_input_win.h @@ -73,7 +73,7 @@ #include "base/win/scoped_com_initializer.h" #include "base/win/scoped_comptr.h" #include "base/win/scoped_handle.h" -#include "media/audio/audio_io.h" +#include "media/audio/audio_input_stream_impl.h" #include "media/audio/audio_parameters.h" #include "media/base/media_export.h" @@ -81,7 +81,7 @@ class AudioManagerWin; // AudioInputStream implementation using Windows Core Audio APIs. class MEDIA_EXPORT WASAPIAudioInputStream - : public AudioInputStream, + : public AudioInputStreamImpl, public base::DelegateSimpleThread::Delegate, NON_EXPORTED_BASE(public base::NonThreadSafe) { public: diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc index 8afa95c..da5acb6 100644 --- a/media/audio/win/audio_low_latency_input_win_unittest.cc +++ b/media/audio/win/audio_low_latency_input_win_unittest.cc @@ -21,6 +21,7 @@ #include "testing/gtest/include/gtest/gtest.h" using base::win::ScopedCOMInitializer; +using ::testing::_; using ::testing::AnyNumber; using ::testing::AtLeast; using ::testing::Gt; @@ -34,9 +35,9 @@ ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) { class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: - MOCK_METHOD4(OnData, void(AudioInputStream* stream, + MOCK_METHOD5(OnData, void(AudioInputStream* stream, const uint8* src, uint32 size, - uint32 hardware_delay_bytes)); + uint32 hardware_delay_bytes, double volume)); MOCK_METHOD1(OnClose, void(AudioInputStream* stream)); MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code)); }; @@ -83,7 +84,8 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size, - uint32 hardware_delay_bytes) { + uint32 hardware_delay_bytes, + double volume) { // Store data data in a temporary buffer to avoid making blocking // fwrite() calls in the audio callback. The complete buffer will be // written to file in the destructor. @@ -306,7 +308,7 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { // All should contain valid packets of the same size and a valid delay // estimate. EXPECT_CALL(sink, OnData( - ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) + ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); @@ -329,7 +331,7 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { (aisw.bits_per_sample() / 8); EXPECT_CALL(sink, OnData( - ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) + ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); @@ -349,7 +351,7 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { (aisw.bits_per_sample() / 8); EXPECT_CALL(sink, OnData( - ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) + ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc index 28dbac8..120a397 100644 --- a/media/audio/win/audio_low_latency_output_win.cc +++ b/media/audio/win/audio_low_latency_output_win.cc @@ -241,6 +241,7 @@ void WASAPIAudioOutputStream::Close() { } void WASAPIAudioOutputStream::SetVolume(double volume) { + DVLOG(1) << "SetVolume(volume=" << volume << ")"; float volume_float = static_cast<float>(volume); if (volume_float < 0.0f || volume_float > 1.0f) { return; @@ -249,6 +250,7 @@ void WASAPIAudioOutputStream::SetVolume(double volume) { } void WASAPIAudioOutputStream::GetVolume(double* volume) { + DVLOG(1) << "GetVolume()"; *volume = static_cast<double>(volume_); } diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc index f8a4e7d..f4055db 100644 --- a/media/audio/win/wavein_input_win.cc +++ b/media/audio/win/wavein_input_win.cc @@ -4,8 +4,6 @@ #include "media/audio/win/wavein_input_win.h" -#include <windows.h> -#include <mmsystem.h> #pragma comment(lib, "winmm.lib") #include "base/logging.h" @@ -15,7 +13,7 @@ #include "media/audio/win/device_enumeration_win.h" namespace { -const int kStopInputStreamCallbackTimeout = 3000; // Three seconds. +const int kStopInputStreamCallbackTimeout = 3000; // Three seconds. } using media::AudioDeviceNames; @@ -201,6 +199,17 @@ double PCMWaveInAudioInputStream::GetVolume() { return 0.0; } +void PCMWaveInAudioInputStream::SetAutomaticGainControl(bool enabled) { + // TODO(henrika): Add AGC support when volume control has been added. + NOTIMPLEMENTED(); +} + +bool PCMWaveInAudioInputStream::GetAutomaticGainControl() { + // TODO(henrika): Add AGC support when volume control has been added. + NOTIMPLEMENTED(); + return false; +} + void PCMWaveInAudioInputStream::HandleError(MMRESULT error) { DLOG(WARNING) << "PCMWaveInAudio error " << error; callback_->OnError(this, error); @@ -260,10 +269,13 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg, // to the callback and check if we need to stop playing. // It should be OK to assume the data in the buffer is what has been // recorded in the soundcard. + // TODO(henrika): the |volume| parameter is always set to zero since there + // is currently no support for controlling the microphone volume level. WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1); obj->callback_->OnData(obj, reinterpret_cast<const uint8*>(buffer->lpData), buffer->dwBytesRecorded, - buffer->dwBytesRecorded); + buffer->dwBytesRecorded, + 0.0); if (obj->state_ == kStateStopping) { // The main thread has called Stop() and is waiting to issue waveOutReset diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h index a9b4b91..b4418d8 100644 --- a/media/audio/win/wavein_input_win.h +++ b/media/audio/win/wavein_input_win.h @@ -5,6 +5,8 @@ #ifndef MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_ #define MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_ +#include <string> + #include <windows.h> #include <mmsystem.h> @@ -36,6 +38,8 @@ class PCMWaveInAudioInputStream : public AudioInputStream { virtual double GetMaxVolume() OVERRIDE; virtual void SetVolume(double volume) OVERRIDE; virtual double GetVolume() OVERRIDE; + virtual void SetAutomaticGainControl(bool enabled) OVERRIDE; + virtual bool GetAutomaticGainControl() OVERRIDE; private: enum State { |