Revert 6090 "Removes parts of the webrtc::VoEHardwareMedia sub A..."
> Removes parts of the webrtc::VoEHardwareMedia sub API as part of a clean-up operation where the goal is to remove unused APIs.
>
> BUG=3206
> R=andrew@webrtc.org, niklas.enbom@webrtc.org
>
> Review URL: https://webrtc-codereview.appspot.com/18399004
TBR=henrika@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/15459004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6091 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/voice_engine/include/voe_hardware.h b/voice_engine/include/voe_hardware.h
index caea208..5c247d7 100644
--- a/voice_engine/include/voe_hardware.h
+++ b/voice_engine/include/voe_hardware.h
@@ -70,6 +70,12 @@
virtual int GetPlayoutDeviceName(int index, char strNameUTF8[128],
char strGuidUTF8[128]) = 0;
+ // Checks if the sound card is available to be opened for recording.
+ virtual int GetRecordingDeviceStatus(bool& isAvailable) = 0;
+
+ // Checks if the sound card is available to be opened for playout.
+ virtual int GetPlayoutDeviceStatus(bool& isAvailable) = 0;
+
// Sets the audio device used for recording.
virtual int SetRecordingDevice(
int index, StereoChannel recordingChannel = kStereoBoth) = 0;
@@ -83,24 +89,47 @@
// Gets the currently used (active) audio device layer.
virtual int GetAudioDeviceLayer(AudioLayers& audioLayer) = 0;
+ // Gets the VoiceEngine's current CPU consumption in terms of the percent
+ // of total CPU availability. [Windows only]
+ virtual int GetCPULoad(int& loadPercent) = 0;
+
+ // Not supported
+ virtual int ResetAudioDevice() = 0;
+
+ // Not supported
+ virtual int AudioDeviceControl(
+ unsigned int par1, unsigned int par2, unsigned int par3) = 0;
+
+ // Not supported
+ virtual int SetLoudspeakerStatus(bool enable) = 0;
+
+ // Not supported
+ virtual int GetLoudspeakerStatus(bool& enabled) = 0;
+
// Native sample rate controls (samples/sec)
virtual int SetRecordingSampleRate(unsigned int samples_per_sec) = 0;
virtual int RecordingSampleRate(unsigned int* samples_per_sec) const = 0;
virtual int SetPlayoutSampleRate(unsigned int samples_per_sec) = 0;
virtual int PlayoutSampleRate(unsigned int* samples_per_sec) const = 0;
- // To be removed. Don't use.
- virtual int EnableBuiltInAEC(bool enable) { return -1; }
- virtual bool BuiltInAECIsEnabled() const { return -1; }
- virtual int GetRecordingDeviceStatus(bool& isAvailable) { return -1; }
- virtual int GetPlayoutDeviceStatus(bool& isAvailable) { return -1; }
- virtual int ResetAudioDevice() { return -1; }
- virtual int AudioDeviceControl(unsigned int par1, unsigned int par2,
- unsigned int par3) { return -1; }
- virtual int SetLoudspeakerStatus(bool enable) { return -1; }
- virtual int GetLoudspeakerStatus(bool& enabled) { return -1; }
- virtual int GetCPULoad(int& loadPercent) { return -1; }
-
+ // *Experimental - not recommended for use.*
+ // Enables the Windows Core Audio built-in AEC. Fails on other platforms.
+ //
+ // Currently incompatible with the standard VoE AEC and AGC; don't attempt
+ // to enable them while this is active.
+ //
+ // Must be called before VoEBase::StartSend(). When enabled:
+ // 1. VoEBase::StartPlayout() must be called before VoEBase::StartSend().
+ // 2. VoEBase::StopSend() should be called before VoEBase::StopPlayout().
+ // The reverse order may cause garbage audio to be rendered or the
+ // capture side to halt until StopSend() is called.
+ //
+ // As a consequence, SetPlayoutDevice() should be used with caution
+ // during a call. It will function, but may cause the above issues for
+ // the duration it takes to complete. (In practice, it should complete
+ // fast enough to avoid audible degradation).
+ virtual int EnableBuiltInAEC(bool enable) = 0;
+ virtual bool BuiltInAECIsEnabled() const = 0;
protected:
VoEHardware() {}
diff --git a/voice_engine/test/auto_test/standard/hardware_before_streaming_test.cc b/voice_engine/test/auto_test/standard/hardware_before_streaming_test.cc
index 0887fd5..e8863c5 100644
--- a/voice_engine/test/auto_test/standard/hardware_before_streaming_test.cc
+++ b/voice_engine/test/auto_test/standard/hardware_before_streaming_test.cc
@@ -51,6 +51,20 @@
"Either you have no recording / playout device "
"on your system, or the method failed.";
+TEST_F(HardwareBeforeStreamingTest, GetPlayoutDeviceStatusReturnsTrue) {
+ bool play_available = false;
+ EXPECT_EQ(0, voe_hardware_->GetPlayoutDeviceStatus(play_available));
+ ASSERT_TRUE(play_available) <<
+ "Ensures that the method works and that hardware is in the right state.";
+}
+
+TEST_F(HardwareBeforeStreamingTest, GetRecordingDeviceStatusReturnsTrue) {
+ bool recording_available = false;
+ EXPECT_EQ(0, voe_hardware_->GetRecordingDeviceStatus(recording_available));
+ EXPECT_TRUE(recording_available) <<
+ "Ensures that the method works and that hardware is in the right state.";
+}
+
// Win, Mac and Linux sound device tests.
TEST_F(HardwareBeforeStreamingTest,
GetRecordingDeviceNameRetrievesDeviceNames) {
diff --git a/voice_engine/test/auto_test/standard/hardware_test.cc b/voice_engine/test/auto_test/standard/hardware_test.cc
index eceef54..fabdf0c 100644
--- a/voice_engine/test/auto_test/standard/hardware_test.cc
+++ b/voice_engine/test/auto_test/standard/hardware_test.cc
@@ -67,3 +67,89 @@
EXPECT_EQ(-1, voe_hardware_->GetCPULoad(load));
}
#endif
+
+// Flakily hangs on Windows: code.google.com/p/webrtc/issues/detail?id=2179.
+TEST_F(HardwareTest,
+ DISABLED_ON_WIN(BuiltInWasapiAECWorksForAudioWindowsCoreAudioLayer)) {
+#ifdef WEBRTC_IOS
+ // Ensure the sound device is reset on iPhone.
+ EXPECT_EQ(0, voe_hardware_->ResetAudioDevice());
+ Sleep(2000);
+#endif
+ EXPECT_EQ(0, voe_base_->StopSend(channel_));
+ EXPECT_EQ(0, voe_base_->StopPlayout(channel_));
+
+ webrtc::AudioLayers given_layer;
+ EXPECT_EQ(0, voe_hardware_->GetAudioDeviceLayer(given_layer));
+ if (given_layer != webrtc::kAudioWindowsCore) {
+ // Not Windows Audio Core - then it shouldn't work.
+ EXPECT_EQ(-1, voe_hardware_->EnableBuiltInAEC(true));
+ EXPECT_EQ(-1, voe_hardware_->EnableBuiltInAEC(false));
+ return;
+ }
+
+ TEST_LOG("Testing AEC for Audio Windows Core.\n");
+ EXPECT_EQ(0, voe_base_->StartSend(channel_));
+
+ // Can't be set after StartSend().
+ EXPECT_EQ(-1, voe_hardware_->EnableBuiltInAEC(true));
+ EXPECT_EQ(-1, voe_hardware_->EnableBuiltInAEC(false));
+
+ EXPECT_EQ(0, voe_base_->StopSend(channel_));
+ EXPECT_EQ(0, voe_hardware_->EnableBuiltInAEC(true));
+
+ // Can't be called before StartPlayout().
+ EXPECT_EQ(-1, voe_base_->StartSend(channel_));
+
+ EXPECT_EQ(0, voe_base_->StartPlayout(channel_));
+ EXPECT_EQ(0, voe_base_->StartSend(channel_));
+ TEST_LOG("Processing capture data with built-in AEC...\n");
+ Sleep(2000);
+
+ TEST_LOG("Looping through capture devices...\n");
+ int num_devs = 0;
+ char dev_name[128] = { 0 };
+ char guid_name[128] = { 0 };
+ EXPECT_EQ(0, voe_hardware_->GetNumOfRecordingDevices(num_devs));
+ for (int dev_index = 0; dev_index < num_devs; ++dev_index) {
+ EXPECT_EQ(0, voe_hardware_->GetRecordingDeviceName(dev_index,
+ dev_name,
+ guid_name));
+ TEST_LOG("%d: %s\n", dev_index, dev_name);
+ EXPECT_EQ(0, voe_hardware_->SetRecordingDevice(dev_index));
+ Sleep(2000);
+ }
+
+ EXPECT_EQ(0, voe_hardware_->SetPlayoutDevice(-1));
+ EXPECT_EQ(0, voe_hardware_->SetRecordingDevice(-1));
+
+ TEST_LOG("Looping through render devices, restarting for each "
+ "device...\n");
+ EXPECT_EQ(0, voe_hardware_->GetNumOfPlayoutDevices(num_devs));
+ for (int dev_index = 0; dev_index < num_devs; ++dev_index) {
+ EXPECT_EQ(0, voe_hardware_->GetPlayoutDeviceName(dev_index,
+ dev_name,
+ guid_name));
+ TEST_LOG("%d: %s\n", dev_index, dev_name);
+ EXPECT_EQ(0, voe_hardware_->SetPlayoutDevice(dev_index));
+ Sleep(2000);
+ }
+
+ TEST_LOG("Using default devices...\n");
+ EXPECT_EQ(0, voe_hardware_->SetRecordingDevice(-1));
+ EXPECT_EQ(0, voe_hardware_->SetPlayoutDevice(-1));
+ Sleep(2000);
+
+ // Possible, but not recommended before StopSend().
+ EXPECT_EQ(0, voe_base_->StopPlayout(channel_));
+
+ EXPECT_EQ(0, voe_base_->StopSend(channel_));
+ EXPECT_EQ(0, voe_base_->StopPlayout(channel_));
+ Sleep(2000); // To verify that there is no garbage audio.
+
+ TEST_LOG("Disabling built-in AEC.\n");
+ EXPECT_EQ(0, voe_hardware_->EnableBuiltInAEC(false));
+
+ EXPECT_EQ(0, voe_base_->StartSend(channel_));
+ EXPECT_EQ(0, voe_base_->StartPlayout(channel_));
+}
diff --git a/voice_engine/voe_hardware_impl.cc b/voice_engine/voe_hardware_impl.cc
index eaf2a28..896572f 100644
--- a/voice_engine/voe_hardware_impl.cc
+++ b/voice_engine/voe_hardware_impl.cc
@@ -528,6 +528,219 @@
return 0;
}
+int VoEHardwareImpl::GetRecordingDeviceStatus(bool& isAvailable)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "GetRecordingDeviceStatus()");
+
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+ // We let the module do isRecording sanity
+
+ bool available(false);
+
+ // Check availability
+ if (_shared->audio_device()->RecordingIsAvailable(&available) != 0)
+ {
+ _shared->SetLastError(VE_UNDEFINED_SC_REC_ERR, kTraceError,
+ " Audio Device error");
+ return -1;
+ }
+
+ isAvailable = available;
+
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+ VoEId(_shared->instance_id(), -1),
+ " Output: isAvailable = %d)", (int) isAvailable);
+
+ return 0;
+}
+
+int VoEHardwareImpl::GetPlayoutDeviceStatus(bool& isAvailable)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "GetPlayoutDeviceStatus()");
+
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+ // We let the module do isPlaying sanity
+
+ bool available(false);
+
+ // Check availability
+ if (_shared->audio_device()->PlayoutIsAvailable(&available) != 0)
+ {
+ _shared->SetLastError(VE_PLAY_UNDEFINED_SC_ERR, kTraceError,
+ " Audio Device error");
+ return -1;
+ }
+
+ isAvailable = available;
+
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+ VoEId(_shared->instance_id(), -1),
+ " Output: isAvailable = %d)", (int) isAvailable);
+
+ return 0;
+}
+
+int VoEHardwareImpl::ResetAudioDevice()
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "ResetAudioDevice()");
+
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+#if defined(WEBRTC_IOS)
+ if (_shared->audio_device()->ResetAudioDevice() < 0)
+ {
+ _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceError,
+ " Failed to reset sound device");
+ return -1;
+ }
+ return 0;
+#else
+ _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
+ " no support for resetting sound device");
+ return -1;
+#endif
+}
+
+int VoEHardwareImpl::AudioDeviceControl(unsigned int par1, unsigned int par2,
+ unsigned int par3)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "AudioDeviceControl(%i, %i, %i)", par1, par2, par3);
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+ _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
+ " no support for resetting sound device");
+ return -1;
+}
+
+int VoEHardwareImpl::SetLoudspeakerStatus(bool enable)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "SetLoudspeakerStatus(enable=%i)", (int) enable);
+
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+#if defined(WEBRTC_ANDROID)
+ if (_shared->audio_device()->SetLoudspeakerStatus(enable) < 0)
+ {
+ _shared->SetLastError(VE_IGNORED_FUNCTION, kTraceError,
+ " Failed to set loudspeaker status");
+ return -1;
+ }
+
+ return 0;
+#else
+ _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
+ " no support for setting loudspeaker status");
+ return -1;
+#endif
+}
+
+int VoEHardwareImpl::GetLoudspeakerStatus(bool& enabled)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "GetLoudspeakerStatus()");
+
+#if defined(WEBRTC_ANDROID)
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+ if (_shared->audio_device()->GetLoudspeakerStatus(&enabled) < 0)
+ {
+ _shared->SetLastError(VE_IGNORED_FUNCTION, kTraceError,
+ " Failed to get loudspeaker status");
+ return -1;
+ }
+
+ return 0;
+#else
+ _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
+ " no support for setting loudspeaker status");
+ return -1;
+#endif
+}
+
+int VoEHardwareImpl::GetCPULoad(int& loadPercent)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "GetCPULoad()");
+
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+ // Get CPU load from ADM
+ uint16_t load(0);
+ if (_shared->audio_device()->CPULoad(&load) != 0)
+ {
+ _shared->SetLastError(VE_CPU_INFO_ERROR, kTraceError,
+ " error getting system CPU load");
+ return -1;
+ }
+
+ loadPercent = static_cast<int> (load);
+
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+ VoEId(_shared->instance_id(), -1),
+ " Output: loadPercent = %d", loadPercent);
+
+ return 0;
+}
+
+int VoEHardwareImpl::EnableBuiltInAEC(bool enable)
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "%s", __FUNCTION__);
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+
+ return _shared->audio_device()->EnableBuiltInAEC(enable);
+}
+
+bool VoEHardwareImpl::BuiltInAECIsEnabled() const
+{
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "%s", __FUNCTION__);
+ if (!_shared->statistics().Initialized())
+ {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return false;
+ }
+
+ return _shared->audio_device()->BuiltInAECIsEnabled();
+}
+
int VoEHardwareImpl::SetRecordingSampleRate(unsigned int samples_per_sec) {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"%s", __FUNCTION__);
diff --git a/voice_engine/voe_hardware_impl.h b/voice_engine/voe_hardware_impl.h
index f3537ef..4e06f97 100644
--- a/voice_engine/voe_hardware_impl.h
+++ b/voice_engine/voe_hardware_impl.h
@@ -33,6 +33,10 @@
char strNameUTF8[128],
char strGuidUTF8[128]);
+ virtual int GetRecordingDeviceStatus(bool& isAvailable);
+
+ virtual int GetPlayoutDeviceStatus(bool& isAvailable);
+
virtual int SetRecordingDevice(
int index,
StereoChannel recordingChannel = kStereoBoth);
@@ -43,6 +47,21 @@
virtual int GetAudioDeviceLayer(AudioLayers& audioLayer);
+ virtual int GetCPULoad(int& loadPercent);
+
+ virtual int ResetAudioDevice();
+
+ virtual int AudioDeviceControl(unsigned int par1,
+ unsigned int par2,
+ unsigned int par3);
+
+ virtual int SetLoudspeakerStatus(bool enable);
+
+ virtual int GetLoudspeakerStatus(bool& enabled);
+
+ virtual int EnableBuiltInAEC(bool enable);
+ virtual bool BuiltInAECIsEnabled() const;
+
virtual int SetRecordingSampleRate(unsigned int samples_per_sec);
virtual int RecordingSampleRate(unsigned int* samples_per_sec) const;
virtual int SetPlayoutSampleRate(unsigned int samples_per_sec);