[DEV] add comment and correct echo cancel

This commit is contained in:
Edouard DUPIN 2015-04-01 21:11:33 +02:00
parent b1d5b8aeab
commit 2483ad9fce
2 changed files with 96 additions and 11 deletions

View File

@ -10,7 +10,7 @@
drain::Lms::Lms(void) :
m_filtre(),
m_feedBack(),
m_micro(0.1f) {
m_mu(0.08f) {
setFilterSize(256);
}
@ -23,7 +23,7 @@ void drain::Lms::reset(void) {
setFilterSize(m_filtre.size());
}
bool drain::Lms::process(int16_t* _output, int16_t* _feedback, int16_t* _microphone, int32_t _nbSample) {
bool drain::Lms::process(int16_t* _output, const int16_t* _feedback, const int16_t* _microphone, int32_t _nbSample) {
float output[_nbSample];
float feedback[_nbSample];
float microphone[_nbSample];
@ -38,7 +38,7 @@ bool drain::Lms::process(int16_t* _output, int16_t* _feedback, int16_t* _microph
return ret;
}
bool drain::Lms::process(float* _output, float* _feedback, float* _microphone, int32_t _nbSample) {
bool drain::Lms::process(float* _output, const float* _feedback, const float* _microphone, int32_t _nbSample) {
// add sample in the feedback history:
m_feedBack.resize(m_filtre.size(), 0.0f);
memcpy(&m_feedBack[m_filtre.size()], _feedback, _nbSample*sizeof(float));
@ -70,7 +70,7 @@ float drain::Lms::processValue(float* _feedback, float _microphone) {
float convolutionValue = convolution(_feedback, &m_filtre[0], m_filtre.size());
float error = _microphone - convolutionValue;
float out = std::avg(-1.0f, error, 1.0f);
updateFilter(&m_filtre[0], _feedback, 2.0f*m_micro, m_filtre.size());
updateFilter(&m_filtre[0], _feedback, error*m_mu, m_filtre.size());
return out;
}

View File

@ -12,24 +12,109 @@
namespace drain {
// Least Mean Square (LMS) algorithm "echo canceller"
/*
Shcématic description:
/
o---o /|
_feedback | |/ |
>---------------->| | | >~~~~~~~~o
x(n) | |\ | |
o---o \| |
\ o--------0
| | Environement
| u(n) | transfert fonction
| |
o--------o
|
|
o---o ___ |
_microphone | |/ \ <~~~~~~o
<----------------<| | | <~~~~~~~~~~~~< Noise
d(n) | |\___/ <~~~~~~0
o---o |
|
o~~~~~< Usefull signal
s(n)
LMS Algorithm:
_microphone -----------------------------o
d(n) |
|
o--------o | o-------------o
o---> filter --------->| | o--->| |
| û(n) | convol-| | d(n) - y(n) |----> e(n) -------> echo-cancelled output
| | -ution |----> y(n) ---->| | |
| _feedback -----o--->| | o-------------o |
| x(n) | o--------o |
| | |
| | o----------------------------------o |
| | | | |
| o-------->| |<-------o
| | û(n+1) = û(n) |
| | + 2 * mu * e(n) * x(n) |
| | |
| o----------------------------------o
| |
| |
o--------------------------------------------o
*/
class Lms {
public:
/**
* @brief Constructor
*/
Lms(void);
/**
* @brief Destructor
*/
~Lms(void);
public:
/**
* @brief Reset filter history and filter
*/
void reset(void);
bool process(int16_t* _output, int16_t* _feedback, int16_t* _microphone, int32_t _nbSample);
bool process(float* _output, float* _feedback, float* _microphone, int32_t _nbSample);
/**
* @brief Process 16 bit LMS (input 16 bits)
* @param[in,out] _output output data of the LMS
* @param[in] _feedback Input feedback of the signal: x(n)
* @param[in] _microphone Input Microphone data: d(n)
*/
bool process(int16_t* _output, const int16_t* _feedback, const int16_t* _microphone, int32_t _nbSample);
/**
* @brief Process float LMS
* @param[in,out] _output output data of the LMS
* @param[in] _feedback Input feedback of the signal: x(n)
* @param[in] _microphone Input Microphone data: d(n)
*/
bool process(float* _output, const float* _feedback, const float* _microphone, int32_t _nbSample);
protected:
/**
* @brief Process a single value of the LMS
* @param[in] _feedback Pointer on the feedback data (with history and at the n(th) position
* @param[in] _microphone Microphone single sample [-1..1]
* @return New output value [-1..1]
*/
float processValue(float* _feedback, float _microphone);
private:
std::vector<float> m_filtre;
std::vector<float> m_feedBack;
public:
/**
* @brief Set filter size with specifing the filter temporal size and his samplerate
* @param[in] _sampleRate Current sample rate to apply filter
* @param[in] _time Time of the filter size
*/
void setFilterSize(size_t _sampleRate, std11::chrono::microseconds _time);
/**
* @brief Set filter size in number of sample
* @param[in] _nbSample Sample size of the filter
*/
void setFilterSize(size_t _nbSample);
protected:
float m_micro; //!< µ step size
private:
std::vector<float> m_filtre; //!< Current filter
std::vector<float> m_feedBack; //!< Feedback history
float m_mu; //!< mu step size
};
}