Commit e95839bc authored by Tristan Matthews's avatar Tristan Matthews

* #15502: audio: removed unused echosuppress/echocancel code

parent 7de89a5a
......@@ -9,8 +9,8 @@ SUBDIRS += pulseaudio
endif
if BUILD_SPEEXDSP
SFL_SPEEXDSP_SRC=echosuppress.cpp speexechocancel.cpp noisesuppress.cpp
SFL_SPEEXDSP_HEAD=echosuppress.h speexechocancel.h noisesuppress.h
SFL_SPEEXDSP_SRC=noisesuppress.cpp
SFL_SPEEXDSP_HEAD=noisesuppress.h
endif
libaudio_la_SOURCES = \
......
......@@ -42,8 +42,6 @@ class SIPCall;
#include "audio/codecs/audiocodec.h"
#include "audio/samplerateconverter.h"
#include "audio/noisesuppress.h"
#include "audio/speexechocancel.h"
#include "audio/echosuppress.h"
#include "audio/gaincontrol.h"
namespace sfl {
......
/*
* EchoSuppress.cpp
*
* Created on: 2011-05-18
* Author: asavard
*/
#include <cassert>
#include <stdexcept>
#include "logger.h"
#include "echosuppress.h"
#include "pjmedia/echo.h"
#include "pj/pool.h"
#include "pj/os.h"
#define SAMPLES_PER_FRAME 160
EchoSuppress::EchoSuppress(pj_pool_t *pool) : echoState_(0)
{
if (pjmedia_echo_create(pool, 8000, SAMPLES_PER_FRAME, 250, 0, PJMEDIA_ECHO_SIMPLE | PJMEDIA_ECHO_NO_LOCK, &echoState_) != PJ_SUCCESS)
throw std::runtime_error("EchoCancel: Could not create echo canceller");
}
EchoSuppress::~EchoSuppress()
{
pjmedia_echo_destroy(echoState_);
}
void EchoSuppress::putData(SFLDataFormat *inputData, int samples)
{
assert(samples == SAMPLES_PER_FRAME);
assert(sizeof(SFLDataFormat) == sizeof(pj_int16_t));
if (pjmedia_echo_playback(echoState_, reinterpret_cast<pj_int16_t *>(inputData)) != PJ_SUCCESS)
WARN("Problem while putting input data");
}
void EchoSuppress::getData(SFLDataFormat *outputData)
{
assert(sizeof(SFLDataFormat) == sizeof(pj_int16_t));
if (pjmedia_echo_capture(echoState_, reinterpret_cast<pj_int16_t *>(outputData), 0) != PJ_SUCCESS)
WARN("Problem while getting output data");
}
/*
* EchoSuppress.h
*
* Created on: 2011-05-18
* Author: asavard
*/
#ifndef ECHOSUPPRESS_H_
#define ECHOSUPPRESS_H_
#include "sfl_types.h"
#include "noncopyable.h"
class pjmedia_echo_state;
class pj_pool_t;
class EchoSuppress {
public:
EchoSuppress(pj_pool_t *pool);
~EchoSuppress();
/**
* Add speaker data into internal buffer
* \param inputData containing far-end voice data to be sent to speakers
*/
void putData(SFLDataFormat *, int);
void getData(SFLDataFormat *);
private:
NON_COPYABLE(EchoSuppress);
/**
* The internal state of the echo canceller
*/
pjmedia_echo_state *echoState_;
};
#endif /* ECHOSUPPRESS_H_ */
/*
* Copyright (C) 2008 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 <fstream>
#include <climits>
#include "speexechocancel.h"
#include "logger.h"
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
#include "manager.h"
namespace {
const int SPEEX_SAMPLE_RATE = 8000;
const int RINGBUFFER_SIZE = 100000;
// number of samples (20 ms)
const size_t EC_FRAME_SIZE = 160;
// number of sample to process, (800 à 4000 samples, 100 to 500 ms)
const size_t EC_FILTER_LENGTH = 800;
}
SpeexEchoCancel::SpeexEchoCancel() :
echoDelay_(Manager::instance().getEchoCancelDelay() * SPEEX_SAMPLE_RATE / 1000),
echoTailLength_(Manager::instance().getEchoCancelTailLength() * SPEEX_SAMPLE_RATE / 1000),
echoState_(speex_echo_state_init(EC_FRAME_SIZE, echoTailLength_)),
preState_(speex_preprocess_state_init(EC_FRAME_SIZE, SPEEX_SAMPLE_RATE)),
micData_(RINGBUFFER_SIZE, MainBuffer::DEFAULT_ID),
spkrData_(RINGBUFFER_SIZE, MainBuffer::DEFAULT_ID),
spkrStopped_(true),
tmpSpkr_(),
tmpMic_(),
tmpOut_()
{
DEBUG("Initializing echo canceller with delay: %d, filter "
"length: %d, frame size: %d and samplerate %d", echoDelay_,
echoTailLength_, EC_FRAME_SIZE, SPEEX_SAMPLE_RATE);
int rate = SPEEX_SAMPLE_RATE;
speex_echo_ctl(echoState_, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);
speex_preprocess_ctl(preState_, SPEEX_PREPROCESS_SET_ECHO_STATE, echoState_);
micData_.createReadPointer(MainBuffer::DEFAULT_ID);
spkrData_.createReadPointer(MainBuffer::DEFAULT_ID);
}
SpeexEchoCancel::~SpeexEchoCancel()
{
speex_echo_state_destroy(echoState_);
speex_preprocess_state_destroy(preState_);
}
void SpeexEchoCancel::putData(SFLDataFormat *inputData, size_t samples)
{
if (spkrStopped_) {
micData_.flushAll();
spkrData_.flushAll();
spkrStopped_ = false;
}
spkrData_.put(inputData, samples * sizeof(SFLDataFormat));
}
int SpeexEchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, size_t samples)
{
if (spkrStopped_)
return 0;
const size_t byteSize = EC_FRAME_SIZE * sizeof(SFLDataFormat);
// init temporary buffers
memset(tmpSpkr_, 0, sizeof(tmpSpkr_));
memset(tmpMic_, 0, sizeof(tmpMic_));
memset(tmpOut_, 0, sizeof(tmpOut_));
// Put mic data in ringbuffer
micData_.put(inputData, samples * sizeof(SFLDataFormat));
// Store data for synchronization
size_t spkrAvail = spkrData_.availableForGet(MainBuffer::DEFAULT_ID);
size_t micAvail = micData_.availableForGet(MainBuffer::DEFAULT_ID);
if ((spkrAvail < (echoDelay_ + byteSize)) or micAvail < byteSize) {
micData_.discard(byteSize, MainBuffer::DEFAULT_ID);
return 0;
}
spkrData_.get(tmpSpkr_, byteSize, MainBuffer::DEFAULT_ID);
micData_.get(tmpMic_, byteSize, MainBuffer::DEFAULT_ID);
for (size_t i = 0; i < EC_FRAME_SIZE; ++i) {
int32_t tmp = tmpSpkr_[i] * 3;
if (tmp > SHRT_MAX)
tmp = SHRT_MAX;
tmpSpkr_[i] = (int16_t)tmp;
tmpMic_[i] /= 3;
}
speex_echo_cancellation(echoState_, tmpMic_, tmpSpkr_, tmpOut_);
speex_preprocess_run(preState_, reinterpret_cast<short *>(tmpOut_));
for (size_t i = 0; i < EC_FRAME_SIZE; i++)
tmpOut_[i] *= 3;
memcpy(outputData, tmpOut_, byteSize);
spkrAvail = spkrData_.availableForGet(MainBuffer::DEFAULT_ID);
micAvail = micData_.availableForGet(MainBuffer::DEFAULT_ID);
return EC_FRAME_SIZE;
}
/*
* Copyright (C) 2008 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 SPEEXECHOCANCEL_H
#define SPEEXECHOCANCEL_H
#include "sfl_types.h"
#include "noncopyable.h"
#include "ringbuffer.h"
class SpeexEchoState_;
typedef SpeexEchoState_ SpeexEchoState;
class SpeexPreprocessState_;
typedef SpeexPreprocessState_ SpeexPreprocessState;
class SpeexEchoCancel {
public:
SpeexEchoCancel();
~SpeexEchoCancel();
/**
* Add speaker data into internal buffer
* \param inputData containing far-end voice data to be sent to speakers
*/
void putData(SFLDataFormat *, size_t samples);
/**
* Perform echo cancellation using internal buffers
* \param inputData containing mixed echo and voice data
* \param outputData containing
*/
int process(SFLDataFormat *, SFLDataFormat *, size_t samples);
private:
NON_COPYABLE(SpeexEchoCancel);
size_t echoDelay_;
size_t echoTailLength_;
SpeexEchoState *echoState_;
SpeexPreprocessState *preState_;
RingBuffer micData_;
RingBuffer spkrData_;
bool spkrStopped_;
SFLDataFormat tmpSpkr_[5000];
SFLDataFormat tmpMic_[5000];
SFLDataFormat tmpOut_[5000];
};
#endif
......@@ -28,8 +28,6 @@ test_SOURCES = constants.h \
siptest.cpp \
sdptest.h \
sdptest.cpp \
echocanceltest.h \
echocanceltest.cpp \
gaincontroltest.h \
gaincontroltest.cpp \
mainbuffertest.h \
......
/*
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 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.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include <iostream>
#include "echocanceltest.h"
#include "config/sfl_config.h"
EchoCancelTest::EchoCancelTest() : echoCanceller_() {}
void EchoCancelTest::testEchoCancelProcessing()
{
using std::ifstream;
using std::ofstream;
SFLDataFormat micData[1000];
SFLDataFormat spkrData[1000];
SFLDataFormat echoCancelData[1000];
// near end input with echo
ifstream micFile("sample_no_echo_8kHz_16bit.raw", ifstream::in);
// far end input to train filter
ifstream spkrFile("sample_ecno_500ms_8kHz_16bit.raw", ifstream::in);
// echo cancelled output
ofstream echoCancelFile("sample_echocancel_500ms_8kHz_16bit.raw", ofstream::out);
micFile.seekg(0, std::ios::end);
size_t inputFileLength = micFile.tellg() / sizeof(SFLDataFormat);
micFile.seekg(0, std::ios::beg);
const int nbSamples = 160;
for (int remainingLength = inputFileLength; remainingLength >= nbSamples; remainingLength -= nbSamples) {
micFile.read(reinterpret_cast<char *>(micData), nbSamples * sizeof(SFLDataFormat));
spkrFile.read(reinterpret_cast<char *>(spkrData), nbSamples * sizeof(SFLDataFormat));
echoCanceller_.putData(spkrData, nbSamples);
echoCanceller_.process(micData, echoCancelData, nbSamples);
echoCancelFile.write(reinterpret_cast<char *>(echoCancelData), nbSamples * sizeof(SFLDataFormat));
}
CPPUNIT_ASSERT(true);
}
/*
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 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.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
/*
* @file audiorecorderTest.cpp
* @brief Regroups unitary tests related to the plugin manager.
*/
#ifndef _AUDIOLAYER_TEST_
#define _AUDIOLAYER_TEST_
// Cppunit import
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestCase.h>
#include <cppunit/TestSuite.h>
#include "audio/speexechocancel.h"
class EchoCancelTest: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(EchoCancelTest);
CPPUNIT_TEST(testEchoCancelProcessing);
CPPUNIT_TEST_SUITE_END();
public:
EchoCancelTest();
void testEchoCancelProcessing();
private:
SpeexEchoCancel echoCanceller_;
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(EchoCancelTest, "EchoCancelTest");
CPPUNIT_TEST_SUITE_REGISTRATION(EchoCancelTest);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment