summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhenrika <henrika@chromium.org>2014-10-16 07:44:12 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-16 14:44:37 +0000
commitc569d98674f56fccf39c53f7ec7a63127755390f (patch)
tree12bc496f1bf71c5c9421f492c63bd8f600682a88
parent15a8709fe24ebb55e15ed88b306d76ad72412931 (diff)
downloadchromium_src-c569d98674f56fccf39c53f7ec7a63127755390f.zip
chromium_src-c569d98674f56fccf39c53f7ec7a63127755390f.tar.gz
chromium_src-c569d98674f56fccf39c53f7ec7a63127755390f.tar.bz2
Add support for audio input mute detection on all platforms.
TBR=rkc@chromium.org BUG=422275 TEST=Manual tests using DVLOGs to confirm valid microphone mute states. Review URL: https://codereview.chromium.org/645923002 Cr-Commit-Position: refs/heads/master@{#299891}
-rw-r--r--components/copresence/mediums/audio/audio_recorder_unittest.cc1
-rw-r--r--content/browser/media/capture/web_contents_audio_input_stream.cc4
-rw-r--r--content/browser/media/capture/web_contents_audio_input_stream.h1
-rw-r--r--media/audio/alsa/alsa_input.cc4
-rw-r--r--media/audio/alsa/alsa_input.h1
-rw-r--r--media/audio/android/audio_record_input.cc5
-rw-r--r--media/audio/android/audio_record_input.h1
-rw-r--r--media/audio/android/opensles_input.cc5
-rw-r--r--media/audio/android/opensles_input.h1
-rw-r--r--media/audio/audio_input_controller.cc29
-rw-r--r--media/audio/audio_io.h3
-rw-r--r--media/audio/cras/cras_input.cc4
-rw-r--r--media/audio/cras/cras_input.h1
-rw-r--r--media/audio/fake_audio_input_stream.cc5
-rw-r--r--media/audio/fake_audio_input_stream.h1
-rw-r--r--media/audio/mac/audio_input_mac.cc5
-rw-r--r--media/audio/mac/audio_input_mac.h1
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.cc23
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.h1
-rw-r--r--media/audio/pulse/pulse_input.cc53
-rw-r--r--media/audio/pulse/pulse_input.h18
-rw-r--r--media/audio/virtual_audio_input_stream.cc4
-rw-r--r--media/audio/virtual_audio_input_stream.h1
-rw-r--r--media/audio/win/audio_low_latency_input_win.cc16
-rw-r--r--media/audio/win/audio_low_latency_input_win.h1
-rw-r--r--media/audio/win/wavein_input_win.cc5
-rw-r--r--media/audio/win/wavein_input_win.h1
27 files changed, 162 insertions, 33 deletions
diff --git a/components/copresence/mediums/audio/audio_recorder_unittest.cc b/components/copresence/mediums/audio/audio_recorder_unittest.cc
index df3f3e5..2c81213 100644
--- a/components/copresence/mediums/audio/audio_recorder_unittest.cc
+++ b/components/copresence/mediums/audio/audio_recorder_unittest.cc
@@ -47,6 +47,7 @@ class TestAudioInputStream : public media::AudioInputStream {
virtual double GetVolume() override { return 1.0; }
virtual void SetAutomaticGainControl(bool enabled) override {}
virtual bool GetAutomaticGainControl() override { return true; }
+ virtual bool IsMuted() override { return false; }
private:
void SimulateRecording() {
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.cc b/content/browser/media/capture/web_contents_audio_input_stream.cc
index ad4fd2f..cdf7eb9 100644
--- a/content/browser/media/capture/web_contents_audio_input_stream.cc
+++ b/content/browser/media/capture/web_contents_audio_input_stream.cc
@@ -391,4 +391,8 @@ bool WebContentsAudioInputStream::GetAutomaticGainControl() {
return impl_->mixer_stream()->GetAutomaticGainControl();
}
+bool WebContentsAudioInputStream::IsMuted() {
+ return false;
+}
+
} // namespace content
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.h b/content/browser/media/capture/web_contents_audio_input_stream.h
index 2f34eed..a0468ff 100644
--- a/content/browser/media/capture/web_contents_audio_input_stream.h
+++ b/content/browser/media/capture/web_contents_audio_input_stream.h
@@ -46,6 +46,7 @@ class CONTENT_EXPORT WebContentsAudioInputStream
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
// Create a new audio mirroring session, or return NULL on error. |device_id|
// should be in the format accepted by
diff --git a/media/audio/alsa/alsa_input.cc b/media/audio/alsa/alsa_input.cc
index 0bc9f31..3c555a0 100644
--- a/media/audio/alsa/alsa_input.cc
+++ b/media/audio/alsa/alsa_input.cc
@@ -336,6 +336,10 @@ double AlsaPcmInputStream::GetVolume() {
return static_cast<double>(current_volume);
}
+bool AlsaPcmInputStream::IsMuted() {
+ return false;
+}
+
void AlsaPcmInputStream::HandleError(const char* method, int error) {
LOG(WARNING) << method << ": " << wrapper_->StrError(error);
callback_->OnError(this);
diff --git a/media/audio/alsa/alsa_input.h b/media/audio/alsa/alsa_input.h
index adc2619..ef7cb2c 100644
--- a/media/audio/alsa/alsa_input.h
+++ b/media/audio/alsa/alsa_input.h
@@ -49,6 +49,7 @@ class AlsaPcmInputStream : public AgcAudioStream<AudioInputStream> {
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
private:
// Logs the error and invokes any registered callbacks.
diff --git a/media/audio/android/audio_record_input.cc b/media/audio/android/audio_record_input.cc
index 3f19588..1dd6118 100644
--- a/media/audio/android/audio_record_input.cc
+++ b/media/audio/android/audio_record_input.cc
@@ -134,4 +134,9 @@ bool AudioRecordInputStream::GetAutomaticGainControl() {
return false;
}
+bool AudioRecordInputStream::IsMuted() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
} // namespace media
diff --git a/media/audio/android/audio_record_input.h b/media/audio/android/audio_record_input.h
index 198fd59..d4c4368 100644
--- a/media/audio/android/audio_record_input.h
+++ b/media/audio/android/audio_record_input.h
@@ -40,6 +40,7 @@ class MEDIA_EXPORT AudioRecordInputStream : public AudioInputStream {
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
static bool RegisterAudioRecordInput(JNIEnv* env);
diff --git a/media/audio/android/opensles_input.cc b/media/audio/android/opensles_input.cc
index 1ef3aac..d8e5f63 100644
--- a/media/audio/android/opensles_input.cc
+++ b/media/audio/android/opensles_input.cc
@@ -185,6 +185,11 @@ bool OpenSLESInputStream::GetAutomaticGainControl() {
return false;
}
+bool OpenSLESInputStream::IsMuted() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
bool OpenSLESInputStream::CreateRecorder() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!engine_object_.Get());
diff --git a/media/audio/android/opensles_input.h b/media/audio/android/opensles_input.h
index 2998e53..ae62639 100644
--- a/media/audio/android/opensles_input.h
+++ b/media/audio/android/opensles_input.h
@@ -43,6 +43,7 @@ class OpenSLESInputStream : public AudioInputStream {
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
private:
bool CreateRecorder();
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 72239f0..3bd14f1 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -583,11 +583,24 @@ void AudioInputController::DoLogAudioLevels(float level_dbfs,
if (!handler_)
return;
+ // Detect if the user has enabled hardware mute by pressing the mute
+ // button in audio settings for the selected microphone.
+ const bool microphone_is_muted = stream_->IsMuted();
+ if (microphone_is_muted) {
+ LogMicrophoneMuteResult(MICROPHONE_IS_MUTED);
+ handler_->OnLog(this, "AIC::OnData: microphone is muted!");
+ // Return early if microphone is muted. No need to adding logs and UMA stats
+ // of audio levels if we know that the micropone is muted.
+ return;
+ }
+
+ LogMicrophoneMuteResult(MICROPHONE_IS_NOT_MUTED);
+
std::string log_string = base::StringPrintf(
"AIC::OnData: average audio level=%.2f dBFS", level_dbfs);
static const float kSilenceThresholdDBFS = -72.24719896f;
if (level_dbfs < kSilenceThresholdDBFS)
- log_string += " <=> no audio input!";
+ log_string += " <=> low audio input level!";
handler_->OnLog(this, log_string);
UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS);
@@ -598,20 +611,6 @@ void AudioInputController::DoLogAudioLevels(float level_dbfs,
if (microphone_volume_percent < kLowLevelMicrophoneLevelPercent)
log_string += " <=> low microphone level!";
handler_->OnLog(this, log_string);
-
- // Try to detect if the user has enabled hardware mute by pressing the mute
- // button in audio settings for the selected microphone. The idea here is to
- // detect when all input samples are zeros but the actual volume slider is
- // larger than zero. It should correspond to a hardware mute state.
- if (level_dbfs == -std::numeric_limits<float>::infinity() &&
- microphone_volume_percent > 0) {
- LogMicrophoneMuteResult(MICROPHONE_IS_MUTED);
- log_string = base::StringPrintf(
- "AIC::OnData: microphone is muted!");
- handler_->OnLog(this, log_string);
- } else {
- LogMicrophoneMuteResult(MICROPHONE_IS_NOT_MUTED);
- }
#endif
}
diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h
index 105e32e..3add053 100644
--- a/media/audio/audio_io.h
+++ b/media/audio/audio_io.h
@@ -164,6 +164,9 @@ class MEDIA_EXPORT AudioInputStream {
// Returns the Automatic Gain Control (AGC) state.
virtual bool GetAutomaticGainControl() = 0;
+
+ // Returns the current muting state for the microphone.
+ virtual bool IsMuted() = 0;
};
} // namespace media
diff --git a/media/audio/cras/cras_input.cc b/media/audio/cras/cras_input.cc
index 0b86446..3fae8df 100644
--- a/media/audio/cras/cras_input.cc
+++ b/media/audio/cras/cras_input.cc
@@ -301,6 +301,10 @@ double CrasInputStream::GetVolume() {
return GetVolumeRatioFromDecibels(dB);
}
+bool CrasInputStream::IsMuted() {
+ return false;
+}
+
double CrasInputStream::GetVolumeRatioFromDecibels(double dB) const {
return pow(10, dB / 20.0);
}
diff --git a/media/audio/cras/cras_input.h b/media/audio/cras/cras_input.h
index 4f5614d..f290f1e 100644
--- a/media/audio/cras/cras_input.h
+++ b/media/audio/cras/cras_input.h
@@ -40,6 +40,7 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> {
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
private:
// Handles requests to get samples from the provided buffer. This will be
diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc
index 74ac579..157d397 100644
--- a/media/audio/fake_audio_input_stream.cc
+++ b/media/audio/fake_audio_input_stream.cc
@@ -203,6 +203,11 @@ double FakeAudioInputStream::GetVolume() {
return 1.0;
}
+bool FakeAudioInputStream::IsMuted() {
+ DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+ return false;
+}
+
void FakeAudioInputStream::SetAutomaticGainControl(bool enabled) {}
bool FakeAudioInputStream::GetAutomaticGainControl() {
diff --git a/media/audio/fake_audio_input_stream.h b/media/audio/fake_audio_input_stream.h
index db00c2e..dba6aaa 100644
--- a/media/audio/fake_audio_input_stream.h
+++ b/media/audio/fake_audio_input_stream.h
@@ -34,6 +34,7 @@ class MEDIA_EXPORT FakeAudioInputStream
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc
index b7f6e17..af5d9bc 100644
--- a/media/audio/mac/audio_input_mac.cc
+++ b/media/audio/mac/audio_input_mac.cc
@@ -136,6 +136,11 @@ double PCMQueueInAudioInputStream::GetVolume() {
return 0.0;
}
+bool PCMQueueInAudioInputStream::IsMuted() {
+ NOTREACHED() << "Only supported for low-latency mode.";
+ return false;
+}
+
void PCMQueueInAudioInputStream::SetAutomaticGainControl(bool enabled) {
NOTREACHED() << "Only supported for low-latency mode.";
}
diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h
index 37afcee..6c1b4a14f 100644
--- a/media/audio/mac/audio_input_mac.h
+++ b/media/audio/mac/audio_input_mac.h
@@ -38,6 +38,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream {
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
private:
// Issue the OnError to |callback_|;
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index 1baa09f..2b2ce00 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -451,6 +451,29 @@ double AUAudioInputStream::GetVolume() {
return 0.0;
}
+bool AUAudioInputStream::IsMuted() {
+ // Verify that we have a valid device.
+ DCHECK_NE(input_device_id_, kAudioObjectUnknown) << "Device ID is unknown";
+
+ AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyMute,
+ kAudioDevicePropertyScopeInput,
+ kAudioObjectPropertyElementMaster
+ };
+
+ if (!AudioObjectHasProperty(input_device_id_, &property_address)) {
+ DLOG(ERROR) << "Device does not support checking master mute state";
+ return false;
+ }
+
+ UInt32 muted = 0;
+ UInt32 size = sizeof(muted);
+ OSStatus result = AudioObjectGetPropertyData(
+ input_device_id_, &property_address, 0, NULL, &size, &muted);
+ DLOG_IF(WARNING, result != noErr) << "Failed to get mute state";
+ return result == noErr && muted != 0;
+}
+
// AUHAL AudioDeviceOutput unit callback
OSStatus AUAudioInputStream::InputProc(void* user_data,
AudioUnitRenderActionFlags* flags,
diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h
index 623cf1d..b3950ffd 100644
--- a/media/audio/mac/audio_low_latency_input_mac.h
+++ b/media/audio/mac/audio_low_latency_input_mac.h
@@ -72,6 +72,7 @@ class AUAudioInputStream : public AgcAudioStream<AudioInputStream> {
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
// Returns the current hardware sample rate for the default input device.
MEDIA_EXPORT static int HardwareSampleRate();
diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc
index 14ef242..7e2ca22 100644
--- a/media/audio/pulse/pulse_input.cc
+++ b/media/audio/pulse/pulse_input.cc
@@ -4,8 +4,6 @@
#include "media/audio/pulse/pulse_input.h"
-#include <pulse/pulseaudio.h>
-
#include "base/logging.h"
#include "media/audio/pulse/audio_manager_pulse.h"
#include "media/audio/pulse/pulse_util.h"
@@ -30,6 +28,7 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager,
channels_(0),
volume_(0.0),
stream_started_(false),
+ muted_(false),
fifo_(params.channels(),
params.frames_per_buffer(),
kNumberOfBlocksBufferInFifo),
@@ -185,20 +184,17 @@ double PulseAudioInputStream::GetVolume() {
// Return zero and the callback will asynchronously update the |volume_|.
return 0.0;
} else {
- // Called by other thread, put an AutoPulseLock and wait for the operation.
- AutoPulseLock auto_lock(pa_mainloop_);
- if (!handle_)
- return 0.0;
-
- size_t index = pa_stream_get_device_index(handle_);
- pa_operation* operation = pa_context_get_source_info_by_index(
- pa_context_, index, &VolumeCallback, this);
- WaitForOperationCompletion(pa_mainloop_, operation);
-
+ GetSourceInformation(&VolumeCallback);
return volume_;
}
}
+bool PulseAudioInputStream::IsMuted() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ GetSourceInformation(&MuteCallback);
+ return muted_;
+}
+
// static, used by pa_stream_set_read_callback.
void PulseAudioInputStream::ReadCallback(pa_stream* handle,
size_t length,
@@ -236,11 +232,32 @@ void PulseAudioInputStream::VolumeCallback(pa_context* context,
stream->volume_ = static_cast<double>(volume);
}
+// static, used by pa_context_get_source_info_by_index.
+void PulseAudioInputStream::MuteCallback(pa_context* context,
+ const pa_source_info* info,
+ int error,
+ void* user_data) {
+ // Runs on PulseAudio callback thread. It might be possible to make this
+ // method more thread safe by passing a struct (or pair) of a local copy of
+ // |pa_mainloop_| and |muted_| instead.
+ PulseAudioInputStream* stream =
+ reinterpret_cast<PulseAudioInputStream*>(user_data);
+
+ // Avoid infinite wait loop in case of error.
+ if (error) {
+ pa_threaded_mainloop_signal(stream->pa_mainloop_, 0);
+ return;
+ }
+
+ stream->muted_ = info->mute != 0;
+}
+
// static, used by pa_stream_set_state_callback.
void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s,
void* user_data) {
PulseAudioInputStream* stream =
reinterpret_cast<PulseAudioInputStream*>(user_data);
+
if (s && stream->callback_ &&
pa_stream_get_state(s) == PA_STREAM_FAILED) {
stream->callback_->OnError(stream);
@@ -301,4 +318,16 @@ void PulseAudioInputStream::ReadData() {
pa_threaded_mainloop_signal(pa_mainloop_, 0);
}
+bool PulseAudioInputStream::GetSourceInformation(pa_source_info_cb_t callback) {
+ AutoPulseLock auto_lock(pa_mainloop_);
+ if (!handle_)
+ return false;
+
+ size_t index = pa_stream_get_device_index(handle_);
+ pa_operation* operation =
+ pa_context_get_source_info_by_index(pa_context_, index, callback, this);
+ WaitForOperationCompletion(pa_mainloop_, operation);
+ return true;
+}
+
} // namespace media
diff --git a/media/audio/pulse/pulse_input.h b/media/audio/pulse/pulse_input.h
index 60acf2f..dd42b31 100644
--- a/media/audio/pulse/pulse_input.h
+++ b/media/audio/pulse/pulse_input.h
@@ -5,6 +5,7 @@
#ifndef MEDIA_AUDIO_PULSE_PULSE_INPUT_H_
#define MEDIA_AUDIO_PULSE_PULSE_INPUT_H_
+#include <pulse/pulseaudio.h>
#include <string>
#include "base/threading/thread_checker.h"
@@ -14,11 +15,6 @@
#include "media/audio/audio_parameters.h"
#include "media/base/audio_block_fifo.h"
-struct pa_context;
-struct pa_source_info;
-struct pa_stream;
-struct pa_threaded_mainloop;
-
namespace media {
class AudioManagerPulse;
@@ -41,6 +37,7 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
private:
// PulseAudio Callbacks.
@@ -48,10 +45,17 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
static void StreamNotifyCallback(pa_stream* stream, void* user_data);
static void VolumeCallback(pa_context* context, const pa_source_info* info,
int error, void* user_data);
+ static void MuteCallback(pa_context* context,
+ const pa_source_info* info,
+ int error,
+ void* user_data);
// Helper for the ReadCallback.
void ReadData();
+ // Utility method used by GetVolume() and IsMuted().
+ bool GetSourceInformation(pa_source_info_cb_t callback);
+
AudioManagerPulse* audio_manager_;
AudioInputCallback* callback_;
std::string device_name_;
@@ -60,6 +64,10 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
double volume_;
bool stream_started_;
+ // Set to true in IsMuted() if user has muted the selected microphone in the
+ // sound settings UI.
+ bool muted_;
+
// Holds the data from the OS.
AudioBlockFifo fifo_;
diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc
index c832a82..6d1189e 100644
--- a/media/audio/virtual_audio_input_stream.cc
+++ b/media/audio/virtual_audio_input_stream.cc
@@ -173,4 +173,8 @@ bool VirtualAudioInputStream::GetAutomaticGainControl() {
return false;
}
+bool VirtualAudioInputStream::IsMuted() {
+ return false;
+}
+
} // namespace media
diff --git a/media/audio/virtual_audio_input_stream.h b/media/audio/virtual_audio_input_stream.h
index 88c92ea..b33dadd 100644
--- a/media/audio/virtual_audio_input_stream.h
+++ b/media/audio/virtual_audio_input_stream.h
@@ -56,6 +56,7 @@ class MEDIA_EXPORT VirtualAudioInputStream : public AudioInputStream {
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
// Attaches a VirtualAudioOutputStream to be used as input. This
// VirtualAudioInputStream must outlive all attached streams, so any attached
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc
index 9fe061b..8df8620 100644
--- a/media/audio/win/audio_low_latency_input_win.cc
+++ b/media/audio/win/audio_low_latency_input_win.cc
@@ -253,7 +253,7 @@ void WASAPIAudioInputStream::SetVolume(double volume) {
}
double WASAPIAudioInputStream::GetVolume() {
- DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully";
+ DCHECK(opened_) << "Open() has not been called successfully";
if (!opened_)
return 0.0;
@@ -265,6 +265,20 @@ double WASAPIAudioInputStream::GetVolume() {
return static_cast<double>(level);
}
+bool WASAPIAudioInputStream::IsMuted() {
+ DCHECK(opened_) << "Open() has not been called successfully";
+ DCHECK(CalledOnValidThread());
+ if (!opened_)
+ return false;
+
+ // Retrieves the current muting state for the audio session.
+ BOOL is_muted = FALSE;
+ HRESULT hr = simple_audio_volume_->GetMute(&is_muted);
+ DLOG_IF(WARNING, FAILED(hr)) << "Failed to get input master volume.";
+
+ return is_muted != FALSE;
+}
+
// static
AudioParameters WASAPIAudioInputStream::GetInputStreamParameters(
const std::string& device_id) {
diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h
index 51feac7..e933a44 100644
--- a/media/audio/win/audio_low_latency_input_win.h
+++ b/media/audio/win/audio_low_latency_input_win.h
@@ -102,6 +102,7 @@ class MEDIA_EXPORT WASAPIAudioInputStream
virtual double GetMaxVolume() override;
virtual void SetVolume(double volume) override;
virtual double GetVolume() override;
+ virtual bool IsMuted() override;
bool started() const { return started_; }
diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc
index e96a877..72c5841 100644
--- a/media/audio/win/wavein_input_win.cc
+++ b/media/audio/win/wavein_input_win.cc
@@ -226,6 +226,11 @@ bool PCMWaveInAudioInputStream::GetAutomaticGainControl() {
return false;
}
+bool PCMWaveInAudioInputStream::IsMuted() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
void PCMWaveInAudioInputStream::HandleError(MMRESULT error) {
DLOG(WARNING) << "PCMWaveInAudio error " << error;
if (callback_)
diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h
index c587ed6..8c22c9b 100644
--- a/media/audio/win/wavein_input_win.h
+++ b/media/audio/win/wavein_input_win.h
@@ -45,6 +45,7 @@ class PCMWaveInAudioInputStream : public AudioInputStream {
virtual double GetVolume() override;
virtual void SetAutomaticGainControl(bool enabled) override;
virtual bool GetAutomaticGainControl() override;
+ virtual bool IsMuted() override;
private:
enum State {