summaryrefslogtreecommitdiffstats
path: root/media/audio/win
diff options
context:
space:
mode:
Diffstat (limited to 'media/audio/win')
-rw-r--r--media/audio/win/audio_low_latency_input_win.cc26
-rw-r--r--media/audio/win/audio_low_latency_input_win.h4
-rw-r--r--media/audio/win/audio_low_latency_input_win_unittest.cc14
-rw-r--r--media/audio/win/audio_low_latency_output_win.cc2
-rw-r--r--media/audio/win/wavein_input_win.cc20
-rw-r--r--media/audio/win/wavein_input_win.h4
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 {