#13882: Make speexdsp and noise suppression and optional dependency

This commit is contained in:
Alexandre Savard
2012-07-26 13:55:49 -04:00
parent 254851a593
commit 6a372a4caf
5 changed files with 102 additions and 13 deletions

View File

@ -161,9 +161,21 @@ PKG_CHECK_MODULES([CCRTP], [libccrtp] >= ${LIBCCRTP_MIN_VERSION},, [
PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev])) PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev]))
]) ])
###############################################################################################################################
# TLS #
# required dependency(ies): libssl #
###############################################################################################################################
dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support
PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development package: libssl-dev])) PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development package: libssl-dev]))
###############################################################################################################################
# ZRTP #
# required dependency(ies): libzrtp #
###############################################################################################################################
dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange
LIBZRTPCPP_MIN_VERSION=1.3.0 LIBZRTPCPP_MIN_VERSION=1.3.0
PKG_CHECK_MODULES(ZRTPCPP, libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development package: libzrtpcpp-dev])) PKG_CHECK_MODULES(ZRTPCPP, libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development package: libzrtpcpp-dev]))
@ -175,6 +187,12 @@ DBUS_CPP_REQUIRED_VERSION=0.6.0-pre1
PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,, PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,,
AC_MSG_ERROR([You need the DBus-c++ libraries (version $DBUS_CPP_REQUIRED_VERSION or better)])) AC_MSG_ERROR([You need the DBus-c++ libraries (version $DBUS_CPP_REQUIRED_VERSION or better)]))
###############################################################################################################################
# Instant Messaging #
# required dependency(ies): libxpat #
###############################################################################################################################
AC_ARG_WITH([instant_messaging], AC_ARG_WITH([instant_messaging],
[ AS_HELP_STRING([--without-instant_messaging], [disable support for instant-messaging]) ], [ AS_HELP_STRING([--without-instant_messaging], [disable support for instant-messaging]) ],
[], [],
@ -190,6 +208,12 @@ AM_CONDITIONAL(BUILD_INSTANT_MESSAGING, test "x$with_instant_messaging" = "xyes"
AX_PTHREAD AX_PTHREAD
###############################################################################################################################
# SDES Key Exchange #
# required dependency(ies): libpcre #
###############################################################################################################################
AC_ARG_WITH([sdes], AC_ARG_WITH([sdes],
[ AS_HELP_STRING([--without-sdes], [disable support for sdes key exchange]) ], [ AS_HELP_STRING([--without-sdes], [disable support for sdes key exchange]) ],
[], [],
@ -206,6 +230,12 @@ dnl Check for libcppunit-dev
CPPUNIT_MIN_VERSION=1.12 CPPUNIT_MIN_VERSION=1.12
PKG_CHECK_MODULES(CPPUNIT, cppunit >= ${CPPUNIT_MIN_VERSION}, AM_CONDITIONAL(BUILD_TEST, test 1 = 1 ), AM_CONDITIONAL(BUILD_TEST, test 0 = 1 )) PKG_CHECK_MODULES(CPPUNIT, cppunit >= ${CPPUNIT_MIN_VERSION}, AM_CONDITIONAL(BUILD_TEST, test 1 = 1 ), AM_CONDITIONAL(BUILD_TEST, test 0 = 1 ))
###############################################################################################################################
# GSM CODEC #
# required dependency(ies): libgsm #
###############################################################################################################################
dnl check for libgsm1 (doesn't use pkg-config) dnl check for libgsm1 (doesn't use pkg-config)
dnl Check for libgsm dnl Check for libgsm
AC_ARG_WITH([gsm], [AS_HELP_STRING([--without-gsm], AC_ARG_WITH([gsm], [AS_HELP_STRING([--without-gsm],
@ -222,6 +252,12 @@ AS_IF([test "x$with_gsm" != xno],
AC_DEFINE_UNQUOTED([HAVE_GSM], `if test "x$with_gsm" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libgsm]) AC_DEFINE_UNQUOTED([HAVE_GSM], `if test "x$with_gsm" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libgsm])
AM_CONDITIONAL(BUILD_GSM, test "x$with_gsm" = "xyes" ) AM_CONDITIONAL(BUILD_GSM, test "x$with_gsm" = "xyes" )
###############################################################################################################################
# SPEEX CODEC #
# required dependency(ies): libspeex #
###############################################################################################################################
dnl Check for libspeex dnl Check for libspeex
AC_ARG_WITH([speex], AC_ARG_WITH([speex],
[AS_HELP_STRING([--without-speex], [AS_HELP_STRING([--without-speex],
@ -239,12 +275,35 @@ AS_IF([test "x$with_speex" != xno],
AC_DEFINE_UNQUOTED([HAVE_SPEEX], `if test "x$with_speex" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeex]) AC_DEFINE_UNQUOTED([HAVE_SPEEX], `if test "x$with_speex" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeex])
AM_CONDITIONAL(BUILD_SPEEX, test "x$with_speex" = "xyes" ) AM_CONDITIONAL(BUILD_SPEEX, test "x$with_speex" = "xyes" )
dnl check in case the libspeexdsp is not installed
AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Unable to find the libspeexdsp headers (you may need to install the libspeexdsp-dev package) used for Noise Suppression and Automatic Gain Control.]))
AC_SEARCH_LIBS([speex_preprocess_run], [speexdsp], [], [
AC_MSG_ERROR([Unable to find speexdsp development files])
])
###############################################################################################################################
# SPEEX DSP #
# required dependency(ies): libspeexdsp #
###############################################################################################################################
dnl check in case the libspeexdsp is not installed
AC_ARG_WITH([speexdsp],
[AS_HELP_STRING([--without-speexdsp],
[disable support for speexdp Noise Suppression and Automatic Gain Control])],
[],
[with_speexdsp=yes])
AS_IF([test "x$with_speexdsp" != xno],
AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Unable to find the libspeexdsp headers (you may need to install the libspeexdsp-dev package) used for Noise Suppression and Automatic Gain Control.]))
AC_SEARCH_LIBS([speex_preprocess_run], [speexdsp],
[],
[AC_MSG_ERROR([Unable to find speexdsp development files])])
])
AC_DEFINE_UNQUOTED([HAVE_SPEEXDSP], `if test "x$with_speexdsp" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeexdsp])
AM_CONDITIONAL(BUILD_SPEEXDSP, test "x$with_speexdsp" = "xyes" )
###############################################################################################################################
# IAX #
# required dependency(ies): libiax2 (static) #
###############################################################################################################################
dnl Check for IAX dnl Check for IAX
AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2], AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2],
[disable support for the iax2 protocol])], [], [with_iax2=yes]) [disable support for the iax2 protocol])], [], [with_iax2=yes])
@ -252,13 +311,21 @@ AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2],
AC_DEFINE_UNQUOTED([HAVE_IAX], `if test "x$with_iax2" = "xyes"; then echo 1; else echo 0;fi`, [Define if you have libiax2]) AC_DEFINE_UNQUOTED([HAVE_IAX], `if test "x$with_iax2" = "xyes"; then echo 1; else echo 0;fi`, [Define if you have libiax2])
AM_CONDITIONAL(USE_IAX, test "x$with_iax2" = "xyes" ) AM_CONDITIONAL(USE_IAX, test "x$with_iax2" = "xyes" )
dnl Check for network-manager
dnl Check for network-manager
AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager], AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager],
[disable support for network-manager events])], [], [disable support for network-manager events])], [],
[with_networkmanager=yes]) [with_networkmanager=yes])
AM_CONDITIONAL(USE_NETWORKMANAGER, test "x$with_networkmanager" = "xyes" ) AM_CONDITIONAL(USE_NETWORKMANAGER, test "x$with_networkmanager" = "xyes" )
###############################################################################################################################
# DOXYGEN #
# required dependency(ies): doxygen #
###############################################################################################################################
# check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/ # check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
AC_DEFUN([BB_ENABLE_DOXYGEN], AC_DEFUN([BB_ENABLE_DOXYGEN],
@ -276,6 +343,8 @@ AC_DEFUN([BB_ENABLE_DOXYGEN],
# Acutally perform the doxygen check # Acutally perform the doxygen check
BB_ENABLE_DOXYGEN BB_ENABLE_DOXYGEN
CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++" CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++"
dnl What to generate dnl What to generate

View File

@ -8,6 +8,11 @@ if BUILD_PULSE
SUBDIRS += pulseaudio SUBDIRS += pulseaudio
endif endif
if BUILD_SPEEXDSP
SFL_SPEEXDSP_SRC=echosuppress.cpp speexechocancel.cpp noisesuppress.cpp
SFL_SPEEXDSP_HEAD=echosuppress.h speexechocancel.h noisesuppress.h
endif
libaudio_la_SOURCES = \ libaudio_la_SOURCES = \
audioloop.cpp \ audioloop.cpp \
ringbuffer.cpp \ ringbuffer.cpp \
@ -18,9 +23,7 @@ libaudio_la_SOURCES = \
audiolayer.cpp \ audiolayer.cpp \
samplerateconverter.cpp \ samplerateconverter.cpp \
delaydetection.cpp \ delaydetection.cpp \
echosuppress.cpp \ $(SFL_SPEEXDSP_SRC) \
speexechocancel.cpp \
noisesuppress.cpp \
gaincontrol.cpp \ gaincontrol.cpp \
dcblocker.cpp dcblocker.cpp
@ -33,9 +36,7 @@ noinst_HEADERS = \
audiolayer.h \ audiolayer.h \
recordable.h \ recordable.h \
delaydetection.h \ delaydetection.h \
echosuppress.h \ $(SFL_SPEEXDSP_HEAD) \
speexechocancel.h \
noisesuppress.h \
gaincontrol.h \ gaincontrol.h \
dcblocker.h \ dcblocker.h \
samplerateconverter.h samplerateconverter.h

View File

@ -70,9 +70,11 @@ AudioRtpRecord::AudioRtpRecord() :
, converterSamplingRate_(0) , converterSamplingRate_(0)
, dtmfQueue_() , dtmfQueue_()
, fadeFactor_(INIT_FADE_IN_FACTOR) , fadeFactor_(INIT_FADE_IN_FACTOR)
#if HAVE_SPEEXDSP
, noiseSuppressEncode_(0) , noiseSuppressEncode_(0)
, noiseSuppressDecode_(0) , noiseSuppressDecode_(0)
, audioProcessMutex_() , audioProcessMutex_()
#endif
, callId_("") , callId_("")
, dtmfPayloadType_(101) // same as Asterisk , dtmfPayloadType_(101) // same as Asterisk
{} {}
@ -87,8 +89,10 @@ AudioRtpRecord::~AudioRtpRecord()
delete converterEncode_; delete converterEncode_;
delete converterDecode_; delete converterDecode_;
delete audioCodec_; delete audioCodec_;
#if HAVE_SPEEXDSP
delete noiseSuppressEncode_; delete noiseSuppressEncode_;
delete noiseSuppressDecode_; delete noiseSuppressDecode_;
#endif
} }
@ -127,6 +131,7 @@ void AudioRtpRecordHandler::initBuffers()
audioRtpRecord_.converterDecode_ = new SamplerateConverter(getCodecSampleRate()); audioRtpRecord_.converterDecode_ = new SamplerateConverter(getCodecSampleRate());
} }
#if HAVE_SPEEXDSP
void AudioRtpRecordHandler::initNoiseSuppress() void AudioRtpRecordHandler::initNoiseSuppress()
{ {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
@ -135,6 +140,7 @@ void AudioRtpRecordHandler::initNoiseSuppress()
delete audioRtpRecord_.noiseSuppressDecode_; delete audioRtpRecord_.noiseSuppressDecode_;
audioRtpRecord_.noiseSuppressDecode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate()); audioRtpRecord_.noiseSuppressDecode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate());
} }
#endif
void AudioRtpRecordHandler::putDtmfEvent(int digit) void AudioRtpRecordHandler::putDtmfEvent(int digit)
{ {
@ -190,11 +196,13 @@ int AudioRtpRecordHandler::processDataEncode()
out = audioRtpRecord_.resampledData_.data(); out = audioRtpRecord_.resampledData_.data();
} }
#if HAVE_SPEEXDSP
if (Manager::instance().audioPreference.getNoiseReduce()) { if (Manager::instance().audioPreference.getNoiseReduce()) {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
assert(audioRtpRecord_.noiseSuppressEncode_); assert(audioRtpRecord_.noiseSuppressEncode_);
audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize()); audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize());
} }
#endif
{ {
ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_); ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
@ -217,12 +225,13 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
inSamples = audioRtpRecord_.audioCodec_->decode(spkrDataDecoded, spkrData, size); inSamples = audioRtpRecord_.audioCodec_->decode(spkrDataDecoded, spkrData, size);
} }
#if HAVE_SPEEXDSP
if (Manager::instance().audioPreference.getNoiseReduce()) { if (Manager::instance().audioPreference.getNoiseReduce()) {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
assert(audioRtpRecord_.noiseSuppressDecode_); assert(audioRtpRecord_.noiseSuppressDecode_);
audioRtpRecord_.noiseSuppressDecode_->process(spkrDataDecoded, getCodecFrameSize()); audioRtpRecord_.noiseSuppressDecode_->process(spkrDataDecoded, getCodecFrameSize());
} }
#endif
audioRtpRecord_.fadeInDecodedData(inSamples); audioRtpRecord_.fadeInDecodedData(inSamples);

View File

@ -90,9 +90,13 @@ class AudioRtpRecord {
int converterSamplingRate_; int converterSamplingRate_;
std::list<DTMFEvent> dtmfQueue_; std::list<DTMFEvent> dtmfQueue_;
SFLDataFormat fadeFactor_; SFLDataFormat fadeFactor_;
#if HAVE_SPEEXDSP
NoiseSuppress *noiseSuppressEncode_; NoiseSuppress *noiseSuppressEncode_;
NoiseSuppress *noiseSuppressDecode_; NoiseSuppress *noiseSuppressDecode_;
ost::Mutex audioProcessMutex_; ost::Mutex audioProcessMutex_;
#endif
std::string callId_; std::string callId_;
unsigned int dtmfPayloadType_; unsigned int dtmfPayloadType_;
@ -146,7 +150,9 @@ class AudioRtpRecordHandler {
void initBuffers(); void initBuffers();
#if HAVE_SPEEXDSP
void initNoiseSuppress(); void initNoiseSuppress();
#endif
/** /**
* Encode audio data from mainbuffer * Encode audio data from mainbuffer

View File

@ -68,11 +68,13 @@ void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec)
Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_); Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_);
#if HAVE_SPEEXDSP
if (lastSamplingRate != audioRtpRecord_.codecSampleRate_) { if (lastSamplingRate != audioRtpRecord_.codecSampleRate_) {
DEBUG("Update noise suppressor with sampling rate %d and frame size %d", DEBUG("Update noise suppressor with sampling rate %d and frame size %d",
getCodecSampleRate(), getCodecFrameSize()); getCodecSampleRate(), getCodecFrameSize());
initNoiseSuppress(); initNoiseSuppress();
} }
#endif
} }
void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec) void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec)
@ -233,7 +235,9 @@ int AudioRtpSession::startRtpThread(AudioCodec &audiocodec)
setSessionTimeouts(); setSessionTimeouts();
setSessionMedia(audiocodec); setSessionMedia(audiocodec);
initBuffers(); initBuffers();
#if HAVE_SPEEXDSP
initNoiseSuppress(); initNoiseSuppress();
#endif
queue_.enableStack(); queue_.enableStack();
thread_.start(); thread_.start();