From a9f25b14990b1522217006727f9b35e3c9a35d10 Mon Sep 17 00:00:00 2001 From: Alexandre Savard <alexandre.savard@savoirfairelinux.net> Date: Tue, 13 Oct 2009 10:17:13 -0400 Subject: [PATCH] [#2253] Add DcBlocker class to remove capture's dc offset --- sflphone-common/src/audio/Makefile.am | 2 + sflphone-common/src/audio/alsa/alsalayer.cpp | 6 +++ sflphone-common/src/audio/alsa/alsalayer.h | 3 ++ sflphone-common/src/audio/audiolayer.h | 1 + sflphone-common/src/audio/dcblocker.cpp | 54 +++++++++++++++++++ sflphone-common/src/audio/dcblocker.h | 40 ++++++++++++++ .../src/audio/pulseaudio/pulselayer.cpp | 5 ++ .../src/audio/pulseaudio/pulselayer.h | 3 ++ sflphone-common/src/sip/sipvoiplink.cpp | 10 ++-- 9 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 sflphone-common/src/audio/dcblocker.cpp create mode 100644 sflphone-common/src/audio/dcblocker.h diff --git a/sflphone-common/src/audio/Makefile.am b/sflphone-common/src/audio/Makefile.am index cfbbf30f31..19e5f45793 100644 --- a/sflphone-common/src/audio/Makefile.am +++ b/sflphone-common/src/audio/Makefile.am @@ -19,6 +19,7 @@ libaudio_la_SOURCES = \ audiolayer.cpp \ audiodevice.cpp \ samplerateconverter.cpp \ + dcblocker.cpp \ $(SPEEX_SOURCES_CPP) noinst_HEADERS = \ @@ -29,6 +30,7 @@ noinst_HEADERS = \ audiodevice.h \ mainbuffer.h \ recordable.h \ + dcblocker.h \ samplerateconverter.h diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index 054f0426ea..92f2fba69a 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.cpp +++ b/sflphone-common/src/audio/alsa/alsalayer.cpp @@ -46,6 +46,8 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager) _audioThread = new AudioThread (this); _urgentRingBuffer.createReadPointer(); + + dcblocker = new DcBlocker(); } // Destructor @@ -57,6 +59,8 @@ AlsaLayer::~AlsaLayer (void) if(_converter) { delete _converter; _converter = NULL; } + + delete dcblocker; dcblocker = NULL; } bool @@ -884,6 +888,8 @@ void AlsaLayer::audioCallback (void) nbSample = _converter->downsampleData ((SFLDataFormat*)in, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up); + dcblocker->filter_signal(rsmpl_out, nbSample); + _mainBuffer.putData(rsmpl_out, nbSample * sizeof (SFLDataFormat), 100); free(rsmpl_out); diff --git a/sflphone-common/src/audio/alsa/alsalayer.h b/sflphone-common/src/audio/alsa/alsalayer.h index aa827afe26..e1d4b189b7 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.h +++ b/sflphone-common/src/audio/alsa/alsalayer.h @@ -22,6 +22,7 @@ #include "audio/audiolayer.h" #include "audio/samplerateconverter.h" +#include "audio/dcblocker.h" #include "eventthread.h" #include <alsa/asoundlib.h> @@ -271,6 +272,8 @@ class AlsaLayer : public AudioLayer { int _converterSamplingRate; + DcBlocker* dcblocker; + }; #endif // _ALSA_LAYER_H_ diff --git a/sflphone-common/src/audio/audiolayer.h b/sflphone-common/src/audio/audiolayer.h index 44fc3036f2..75921da755 100644 --- a/sflphone-common/src/audio/audiolayer.h +++ b/sflphone-common/src/audio/audiolayer.h @@ -299,6 +299,7 @@ class AudioLayer { int _errorMessage; ost::Mutex _mutex; + }; #endif // _AUDIO_LAYER_H_ diff --git a/sflphone-common/src/audio/dcblocker.cpp b/sflphone-common/src/audio/dcblocker.cpp new file mode 100644 index 0000000000..c19b3ccc7c --- /dev/null +++ b/sflphone-common/src/audio/dcblocker.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + + +#include "dcblocker.h" + +DcBlocker::DcBlocker(){ + + y = 0; + x = 0; + xm1 = 0; + ym1 = 0; + +} + +DcBlocker::~DcBlocker(){ + + +} + +void DcBlocker::filter_signal(SFLDataFormat* audio_data, int length) +{ + // y(n) = x(n) - x(n-1) + R y(n-1) , R = 0.9999 + + for(int i = 0; i < length; i++) { + + x = audio_data[i]; + + y = (SFLDataFormat)((float)x - (float)xm1 + 0.9999 * (float)ym1); + xm1 = x; + ym1 = y; + + audio_data[i] = y; + + } + +} diff --git a/sflphone-common/src/audio/dcblocker.h b/sflphone-common/src/audio/dcblocker.h new file mode 100644 index 0000000000..0fab731678 --- /dev/null +++ b/sflphone-common/src/audio/dcblocker.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DCBLOCKER_H +#define DCBLOCKER_H + +#include "global.h" + +class DcBlocker { + +public: + + DcBlocker(); + + ~DcBlocker(); + + void filter_signal(SFLDataFormat* audio_data, int length); + +private: + + SFLDataFormat y, x, xm1, ym1; +}; + +#endif diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp index 47e0090d63..e8ae5f0521 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp @@ -41,6 +41,7 @@ PulseLayer::PulseLayer (ManagerImpl* manager) _debug ("PulseLayer::Pulse audio constructor: Create context\n"); _urgentRingBuffer.createReadPointer(); + dcblocker = new DcBlocker(); } // Destructor @@ -51,6 +52,8 @@ PulseLayer::~PulseLayer (void) if (_converter) { delete _converter; _converter = NULL; } + + delete dcblocker; dcblocker = NULL; } bool @@ -486,6 +489,8 @@ void PulseLayer::readFromMic (void) nbSample = _converter->downsampleData ((SFLDataFormat*)data, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up); + // remove dc offset + dcblocker->filter_signal( rsmpl_out, nbSample ); _mainBuffer.putData ( (void*) rsmpl_out, nbSample*sizeof(SFLDataFormat), 100); diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.h b/sflphone-common/src/audio/pulseaudio/pulselayer.h index 3fd54cec7d..efe0e7f3fd 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.h +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.h @@ -22,6 +22,7 @@ #include "audio/audiolayer.h" #include "audio/samplerateconverter.h" +#include "audio/dcblocker.h" #include "audiostream.h" #include <pulse/pulseaudio.h> @@ -198,6 +199,8 @@ class PulseLayer : public AudioLayer { int spkrVolume; int micVolume; + DcBlocker* dcblocker; + // private: public: diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 26108d4999..095185b41e 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -594,8 +594,8 @@ int SIPVoIPLink::sendRegister (AccountID id) pjsip_tpselector *tp; - init_transport_selector (account->getAccountTransport (), &tp); - status = pjsip_regc_set_transport (regc, tp); + // init_transport_selector (account->getAccountTransport (), &tp); + // status = pjsip_regc_set_transport (regc, tp); if (status != PJ_SUCCESS) { _debug ("UserAgent: Unable to set transport.\n"); @@ -1322,9 +1322,9 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) call->setInvSession (inv); // Set the appropriate transport - pjsip_tpselector *tp; - init_transport_selector (account->getAccountTransport (), &tp); - status = pjsip_dlg_set_transport (dialog, tp); + // pjsip_tpselector *tp; + // init_transport_selector (account->getAccountTransport (), &tp); + // status = pjsip_dlg_set_transport (dialog, tp); status = pjsip_inv_send_msg (inv, tdata); -- GitLab