Add support for clock drift compensation.
Support clock drift compensation on Windows and add an API to allow enabling dynamically. BUG=issue773 TEST=unittest, trybots Review URL: https://webrtc-codereview.appspot.com/744007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2683 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
954cf806d9
commit
55c0d4a683
@ -97,6 +97,15 @@ public:
|
||||
// Gets the EC status and mode.
|
||||
virtual int GetEcStatus(bool& enabled, EcModes& mode) = 0;
|
||||
|
||||
// Enables the compensation of clock drift between the capture and render
|
||||
// streams by the echo canceller (i.e. only using EcMode==kEcAec). It will
|
||||
// only be enabled if supported on the current platform; otherwise an error
|
||||
// will be returned. Check if the platform is supported by calling
|
||||
// |DriftCompensationSupported()|.
|
||||
virtual int EnableDriftCompensation(bool enable) = 0;
|
||||
virtual bool DriftCompensationEnabled() = 0;
|
||||
static bool DriftCompensationSupported();
|
||||
|
||||
// Sets a delay |offset| in ms to add to the system delay reported by the
|
||||
// OS, which is used by the AEC to synchronize far- and near-end streams.
|
||||
// In some cases a system may introduce a delay which goes unreported by the
|
||||
|
||||
@ -25,6 +25,23 @@
|
||||
VoEId(_shared->instance_id(), -1), __FUNCTION__); \
|
||||
} while (0)
|
||||
|
||||
#define WEBRTC_VOICE_INIT_CHECK() \
|
||||
do { \
|
||||
if (!_shared->statistics().Initialized()) { \
|
||||
_shared->SetLastError(VE_NOT_INITED, kTraceError); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WEBRTC_VOICE_INIT_CHECK_BOOL() \
|
||||
do { \
|
||||
if (!_shared->statistics().Initialized()) { \
|
||||
_shared->SetLastError(VE_NOT_INITED, kTraceError); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
#if defined(WEBRTC_ANDROID) || defined(MAC_IPHONE) || defined(MAC_IPHONE_SIM)
|
||||
@ -48,7 +65,8 @@ VoEAudioProcessing* VoEAudioProcessing::GetInterface(VoiceEngine* voiceEngine) {
|
||||
|
||||
#ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
|
||||
VoEAudioProcessingImpl::VoEAudioProcessingImpl(voe::SharedData* shared)
|
||||
: _isAecMode(kDefaultEcMode == kEcAec), _shared(shared) {
|
||||
: _isAecMode(kDefaultEcMode == kEcAec),
|
||||
_shared(shared) {
|
||||
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
|
||||
"VoEAudioProcessingImpl::VoEAudioProcessingImpl() - ctor");
|
||||
}
|
||||
@ -487,6 +505,41 @@ int VoEAudioProcessingImpl::GetRxAgcConfig(int channel, AgcConfig& config) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VoEAudioProcessing::DriftCompensationSupported() {
|
||||
#if defined(WEBRTC_DRIFT_COMPENSATION_SUPPORTED)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int VoEAudioProcessingImpl::EnableDriftCompensation(bool enable) {
|
||||
WEBRTC_TRACE_VOICE_API();
|
||||
WEBRTC_VOICE_INIT_CHECK();
|
||||
|
||||
if (!DriftCompensationSupported()) {
|
||||
_shared->SetLastError(VE_APM_ERROR, kTraceWarning,
|
||||
"Drift compensation is not supported on this platform.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
|
||||
if (aec->enable_drift_compensation(enable) != 0) {
|
||||
_shared->SetLastError(VE_APM_ERROR, kTraceError,
|
||||
"aec->enable_drift_compensation() failed");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VoEAudioProcessingImpl::DriftCompensationEnabled() {
|
||||
WEBRTC_TRACE_VOICE_API();
|
||||
WEBRTC_VOICE_INIT_CHECK_BOOL();
|
||||
|
||||
EchoCancellation* aec = _shared->audio_processing()->echo_cancellation();
|
||||
return aec->is_drift_compensation_enabled();
|
||||
}
|
||||
|
||||
int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
|
||||
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
|
||||
"SetEcStatus(enable=%d, mode=%d)", enable, mode);
|
||||
@ -520,21 +573,6 @@ int VoEAudioProcessingImpl::SetEcStatus(bool enable, EcModes mode) {
|
||||
"SetEcStatus() failed to set AEC state");
|
||||
return -1;
|
||||
}
|
||||
#ifdef CLOCK_SKEW_COMP
|
||||
if (_shared->audio_processing()->echo_cancellation()->
|
||||
enable_drift_compensation(true) != 0) {
|
||||
_shared->SetLastError(VE_APM_ERROR, kTraceError,
|
||||
"SetEcStatus() failed to enable drift compensation");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (_shared->audio_processing()->echo_cancellation()->
|
||||
enable_drift_compensation(false) != 0) {
|
||||
_shared->SetLastError(VE_APM_ERROR, kTraceError,
|
||||
"SetEcStatus() failed to disable drift compensation");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (mode == kEcConference) {
|
||||
if (_shared->audio_processing()->echo_cancellation()->
|
||||
set_suppression_level(EchoCancellation::kHighSuppression) != 0) {
|
||||
@ -1111,8 +1149,6 @@ bool VoEAudioProcessingImpl::IsStereoChannelSwappingEnabled() {
|
||||
return _shared->transmit_mixer()->IsStereoChannelSwappingEnabled();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // #ifdef WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -48,11 +48,11 @@ class VoEAudioProcessingImpl : public VoEAudioProcessing {
|
||||
virtual int GetRxAgcConfig(int channel, AgcConfig& config);
|
||||
|
||||
virtual int SetEcStatus(bool enable, EcModes mode = kEcUnchanged);
|
||||
|
||||
virtual int GetEcStatus(bool& enabled, EcModes& mode);
|
||||
virtual int EnableDriftCompensation(bool enable);
|
||||
virtual bool DriftCompensationEnabled();
|
||||
|
||||
virtual void SetDelayOffsetMs(int offset);
|
||||
|
||||
virtual int DelayOffsetMs();
|
||||
|
||||
virtual int SetAecmMode(AecmModes mode = kAecmSpeakerphone,
|
||||
|
||||
64
src/voice_engine/voe_audio_processing_unittest.cc
Normal file
64
src/voice_engine/voe_audio_processing_unittest.cc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "voice_engine/include/voe_audio_processing.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "voice_engine/include/voe_base.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace voe {
|
||||
namespace {
|
||||
|
||||
class VoEAudioProcessingTest : public ::testing::Test {
|
||||
protected:
|
||||
VoEAudioProcessingTest()
|
||||
: voe_(VoiceEngine::Create()),
|
||||
base_(VoEBase::GetInterface(voe_)),
|
||||
audioproc_(VoEAudioProcessing::GetInterface(voe_)) {
|
||||
}
|
||||
|
||||
virtual ~VoEAudioProcessingTest() {
|
||||
audioproc_->Release();
|
||||
base_->Release();
|
||||
VoiceEngine::Delete(voe_);
|
||||
}
|
||||
|
||||
VoiceEngine* voe_;
|
||||
VoEBase* base_;
|
||||
VoEAudioProcessing* audioproc_;
|
||||
};
|
||||
|
||||
TEST_F(VoEAudioProcessingTest, FailureIfNotInitialized) {
|
||||
EXPECT_EQ(-1, audioproc_->EnableDriftCompensation(true));
|
||||
EXPECT_EQ(-1, audioproc_->EnableDriftCompensation(false));
|
||||
EXPECT_FALSE(audioproc_->DriftCompensationEnabled());
|
||||
}
|
||||
|
||||
// TODO(andrew): Ideally, DriftCompensationSupported() would be mocked for this.
|
||||
TEST_F(VoEAudioProcessingTest, DriftCompensationIsEnabledIfSupported) {
|
||||
ASSERT_EQ(0, base_->Init());
|
||||
bool supported = VoEAudioProcessing::DriftCompensationSupported();
|
||||
if (supported) {
|
||||
EXPECT_EQ(0, audioproc_->EnableDriftCompensation(true));
|
||||
EXPECT_TRUE(audioproc_->DriftCompensationEnabled());
|
||||
EXPECT_EQ(0, audioproc_->EnableDriftCompensation(false));
|
||||
EXPECT_FALSE(audioproc_->DriftCompensationEnabled());
|
||||
} else {
|
||||
EXPECT_EQ(-1, audioproc_->EnableDriftCompensation(true));
|
||||
EXPECT_FALSE(audioproc_->DriftCompensationEnabled());
|
||||
EXPECT_EQ(-1, audioproc_->EnableDriftCompensation(false));
|
||||
EXPECT_FALSE(audioproc_->DriftCompensationEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace voe
|
||||
} // namespace webrtc
|
||||
@ -118,6 +118,9 @@
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'defines': ['WEBRTC_DRIFT_COMPENSATION_SUPPORTED',],
|
||||
}],
|
||||
['include_tests==1', {
|
||||
'targets': [
|
||||
{
|
||||
@ -146,6 +149,7 @@
|
||||
'sources': [
|
||||
'channel_unittest.cc',
|
||||
'output_mixer_unittest.cc',
|
||||
'voe_audio_processing_unittest.cc',
|
||||
],
|
||||
},
|
||||
], # targets
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user