[DEV] import echo canceller from drain
This commit is contained in:
commit
b19a5a93a0
64
.gitignore
vendored
Normal file
64
.gitignore
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
###################################
|
||||
# folders
|
||||
###################################
|
||||
CVS
|
||||
.svn
|
||||
Object_*
|
||||
doxygen/API/
|
||||
doxygen/ALL/
|
||||
|
||||
###################################
|
||||
# backup files
|
||||
###################################
|
||||
*~
|
||||
*.swp
|
||||
*.old
|
||||
*.bck
|
||||
|
||||
###################################
|
||||
# Compiled source #
|
||||
###################################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
*.pyc
|
||||
tags
|
||||
#ewol
|
||||
out
|
||||
ewol_debug
|
||||
ewol_release
|
||||
|
||||
###################################
|
||||
# Packages #
|
||||
###################################
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
###################################
|
||||
# Logs and databases #
|
||||
###################################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
###################################
|
||||
# OS generated files #
|
||||
###################################
|
||||
.DS_Store?
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
Sources/libewol/ewol/os/AndroidAbstraction.cpp
|
||||
org_ewol_EwolConstants.h
|
46
README.md
Normal file
46
README.md
Normal file
@ -0,0 +1,46 @@
|
||||
[![Build Status](https://secure.travis-ci.org/HeeroYui/audio-algo-aec.svg?branch=master)](https://travis-ci.org/HeeroYui/audio-algo-aec)
|
||||
|
||||
E-AEC
|
||||
=====
|
||||
|
||||
`audio-algo-aec` (audio algo: Acoustic Echo Cancel) is a FREE software.
|
||||
|
||||
This is a part of bacis algorithms
|
||||
|
||||
Instructions
|
||||
============
|
||||
|
||||
download the software :
|
||||
|
||||
mkdir my_workspace
|
||||
cd my_workspace
|
||||
git clone git://github.com/HeeroYui/etk.git
|
||||
git clone git://github.com/HeeroYui/audio-algo-aec.git
|
||||
git clone git://github.com/HeeroYui/lutin.git
|
||||
|
||||
Compile software and install :
|
||||
|
||||
lutin/lutin.py audio_algo_aec_test
|
||||
|
||||
Dependency packages
|
||||
===================
|
||||
|
||||
sudo apt-get install g++
|
||||
|
||||
License (APACHE v2.0)
|
||||
=====================
|
||||
|
||||
Copyright audio-algo-aec Edouard DUPIN
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
90
audio/algo/aec/Lms.cpp
Normal file
90
audio/algo/aec/Lms.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <audio/algo/aec/debug.h>
|
||||
#include <audio/algo/aec/Lms.h>
|
||||
|
||||
audio::algo::aec::Lms::Lms(void) :
|
||||
m_filter(),
|
||||
m_feedBack(),
|
||||
m_mu(0.03f) {
|
||||
setFilterSize(256);
|
||||
}
|
||||
|
||||
audio::algo::aec::Lms::~Lms(void) {
|
||||
|
||||
}
|
||||
|
||||
void audio::algo::aec::Lms::reset(void) {
|
||||
// simply reset filters.
|
||||
setFilterSize(m_filter.size());
|
||||
}
|
||||
|
||||
bool audio::algo::aec::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];
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
microphone[iii] = float(_microphone[iii])/32767.0f;
|
||||
feedback[iii] = float(_feedback[iii])/32767.0f;
|
||||
}
|
||||
bool ret = process(output, feedback, microphone, _nbSample);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
_output[iii] = int16_t(float(output[iii])*32767.0f);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool audio::algo::aec::Lms::process(float* _output, const float* _feedback, const float* _microphone, int32_t _nbSample) {
|
||||
// add sample in the feedback history:
|
||||
m_feedBack.resize(m_filter.size()+_nbSample, 0.0f);
|
||||
memcpy(&m_feedBack[m_filter.size()], _feedback, _nbSample*sizeof(float));
|
||||
for (int32_t iii=0; iii < _nbSample; iii++) {
|
||||
_output[iii] = processValue(&m_feedBack[m_filter.size()+iii], _microphone[iii]);
|
||||
}
|
||||
// remove old value:
|
||||
m_feedBack.erase(m_feedBack.begin(), m_feedBack.begin() + (m_feedBack.size()-m_filter.size()) );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static float convolution(float* _dataMinus, float* _dataPlus, size_t _count) {
|
||||
float out = 0.0f;
|
||||
for (size_t iii = 0; iii < _count; ++iii) {
|
||||
out += *_dataMinus-- * *_dataPlus++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void updateFilter(float* _filter, float* _data, float _value, int32_t _count) {
|
||||
for (size_t iii = 0; iii < _count; ++iii) {
|
||||
*(_filter++) += *_data-- * _value;
|
||||
}
|
||||
}
|
||||
|
||||
float audio::algo::aec::Lms::processValue(float* _feedback, float _microphone) {
|
||||
// Error calculation.
|
||||
float convolutionValue = convolution(_feedback, &m_filter[0], m_filter.size());
|
||||
float error = _microphone - convolutionValue;
|
||||
float out = std::avg(-1.0f, error, 1.0f);
|
||||
updateFilter(&m_filter[0], _feedback, error*m_mu, m_filter.size());
|
||||
return out;
|
||||
}
|
||||
|
||||
void audio::algo::aec::Lms::setFilterSize(size_t _sampleRate, std11::chrono::microseconds _time) {
|
||||
setFilterSize((_sampleRate*_time.count())/1000000LL);
|
||||
}
|
||||
|
||||
void audio::algo::aec::Lms::setFilterSize(size_t _nbSample) {
|
||||
m_filter.clear();
|
||||
m_feedBack.clear();
|
||||
m_filter.resize(_nbSample, 0.0f);
|
||||
m_feedBack.resize(_nbSample, 0.0f);
|
||||
}
|
||||
|
||||
void audio::algo::aec::Lms::setMu(float _val) {
|
||||
m_mu = _val;
|
||||
}
|
135
audio/algo/aec/Lms.h
Normal file
135
audio/algo/aec/Lms.h
Normal file
@ -0,0 +1,135 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __DRAIN_LMS_H__
|
||||
#define __DRAIN_LMS_H__
|
||||
|
||||
#include <etk/types.h>
|
||||
#include <etk/chrono.h>
|
||||
namespace audio {
|
||||
namespace algo {
|
||||
namespace aec {
|
||||
/**
|
||||
* @brief Least Mean Square (LMS) algorithm "echo canceller"
|
||||
* base on publication: http://www.arpapress.com/Volumes/Vol7Issue1/IJRRAS_7_1_05.pdf
|
||||
Electronic 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);
|
||||
/**
|
||||
* @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);
|
||||
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);
|
||||
/**
|
||||
* @brief Set Mu value for basic LMS value
|
||||
* @param[in] _val new mu value
|
||||
*/
|
||||
void setMu(float _val);
|
||||
private:
|
||||
std::vector<float> m_filter; //!< Current filter
|
||||
std::vector<float> m_feedBack; //!< Feedback history
|
||||
float m_mu; //!< mu step size
|
||||
public:
|
||||
// for debug only:
|
||||
std::vector<float> getFilter() {
|
||||
return m_filter;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
14
audio/algo/aec/debug.cpp
Normal file
14
audio/algo/aec/debug.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
int32_t audio::algo::aec::getLogId() {
|
||||
static int32_t g_val = etk::log::registerInstance("audio-algo-aec");
|
||||
return g_val;
|
||||
}
|
||||
|
45
audio/algo/aec/debug.h
Normal file
45
audio/algo/aec/debug.h
Normal file
@ -0,0 +1,45 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __APPL_DEBUG_H__
|
||||
#define __APPL_DEBUG_H__
|
||||
|
||||
#include <etk/log.h>
|
||||
|
||||
namespace audio {
|
||||
namespace algo {
|
||||
namespace aec {
|
||||
int32_t getLogId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define AA_AEC_BASE(info,data) TK_LOG_BASE(audio::algo::aec::getLogId(),info,data)
|
||||
|
||||
#define AA_AEC_CRITICAL(data) AA_AEC_BASE(1, data)
|
||||
#define AA_AEC_ERROR(data) AA_AEC_BASE(2, data)
|
||||
#define AA_AEC_WARNING(data) AA_AEC_BASE(3, data)
|
||||
#ifdef DEBUG
|
||||
#define AA_AEC_INFO(data) AA_AEC_BASE(4, data)
|
||||
#define AA_AEC_DEBUG(data) AA_AEC_BASE(5, data)
|
||||
#define AA_AEC_VERBOSE(data) AA_AEC_BASE(6, data)
|
||||
#define AA_AEC_TODO(data) AA_AEC_BASE(4, "TODO : " << data)
|
||||
#else
|
||||
#define AA_AEC_INFO(data) do { } while(false)
|
||||
#define AA_AEC_DEBUG(data) do { } while(false)
|
||||
#define AA_AEC_VERBOSE(data) do { } while(false)
|
||||
#define AA_AEC_TODO(data) do { } while(false)
|
||||
#endif
|
||||
|
||||
#define AA_AEC_ASSERT(cond,data) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
APPL_CRITICAL(data); \
|
||||
assert(!#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
13
license.txt
Normal file
13
license.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright audio-algo-aec Edouard DUPIN
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
28
lutin_audio_algo_aec.py
Normal file
28
lutin_audio_algo_aec.py
Normal file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/python
|
||||
import lutinModule as module
|
||||
import lutinTools as tools
|
||||
import lutinDebug as debug
|
||||
|
||||
def get_desc():
|
||||
return "audio_algo_aec : AEC basic algo"
|
||||
|
||||
|
||||
def create(target):
|
||||
myModule = module.Module(__file__, 'audio_algo_aec', 'LIBRARY')
|
||||
myModule.add_src_file([
|
||||
'audio/algo/aec/debug.cpp',
|
||||
'audio/algo/aec/Lms.cpp'
|
||||
])
|
||||
myModule.add_module_depend(['etk'])
|
||||
myModule.add_export_path(tools.get_current_path(__file__))
|
||||
# return module
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
26
lutin_audio_algo_aec_test.py
Normal file
26
lutin_audio_algo_aec_test.py
Normal file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/python
|
||||
import lutinModule as module
|
||||
import lutinTools as tools
|
||||
import lutinDebug as debug
|
||||
|
||||
def get_desc():
|
||||
return "audio_algo_aec_test: test for LMS ALGO"
|
||||
|
||||
|
||||
def create(target):
|
||||
myModule = module.Module(__file__, 'audio_algo_aec_test', 'BINARY')
|
||||
myModule.add_src_file([
|
||||
'test/main.cpp',
|
||||
'test/debug.cpp'
|
||||
])
|
||||
myModule.add_module_depend(['audio_algo_aec'])
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
publication/IJRRAS_7_1_05.pdf
Normal file
BIN
publication/IJRRAS_7_1_05.pdf
Normal file
Binary file not shown.
13
test/debug.cpp
Normal file
13
test/debug.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
int32_t appl::getLogId() {
|
||||
static int32_t g_val = etk::log::registerInstance("test-LMS");
|
||||
return g_val;
|
||||
}
|
||||
|
41
test/debug.h
Normal file
41
test/debug.h
Normal file
@ -0,0 +1,41 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __APPL_DEBUG_H__
|
||||
#define __APPL_DEBUG_H__
|
||||
|
||||
#include <etk/log.h>
|
||||
|
||||
namespace appl {
|
||||
int32_t getLogId();
|
||||
};
|
||||
|
||||
#define APPL_BASE(info,data) TK_LOG_BASE(appl::getLogId(),info,data)
|
||||
|
||||
#define APPL_CRITICAL(data) APPL_BASE(1, data)
|
||||
#define APPL_ERROR(data) APPL_BASE(2, data)
|
||||
#define APPL_WARNING(data) APPL_BASE(3, data)
|
||||
#ifdef DEBUG
|
||||
#define APPL_INFO(data) APPL_BASE(4, data)
|
||||
#define APPL_DEBUG(data) APPL_BASE(5, data)
|
||||
#define APPL_VERBOSE(data) APPL_BASE(6, data)
|
||||
#define APPL_TODO(data) APPL_BASE(4, "TODO : " << data)
|
||||
#else
|
||||
#define APPL_INFO(data) do { } while(false)
|
||||
#define APPL_DEBUG(data) do { } while(false)
|
||||
#define APPL_VERBOSE(data) do { } while(false)
|
||||
#define APPL_TODO(data) do { } while(false)
|
||||
#endif
|
||||
|
||||
#define APPL_ASSERT(cond,data) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
APPL_CRITICAL(data); \
|
||||
assert(!#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
113
test/main.cpp
Normal file
113
test/main.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2015, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <test/debug.h>
|
||||
#include <etk/etk.h>
|
||||
#include <audio/algo/aec/Lms.h>
|
||||
#include <etk/os/FSNode.h>
|
||||
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "test"
|
||||
|
||||
|
||||
static std::vector<int16_t> read(const std::string& _path) {
|
||||
std::vector<int16_t> out;
|
||||
etk::FSNode node(_path);
|
||||
if (node.fileOpenRead() == false) {
|
||||
APPL_ERROR("can not open file : '" << node << "'");
|
||||
return out;
|
||||
}
|
||||
uint64_t nbByte = node.fileSize();
|
||||
out.resize(nbByte/2);
|
||||
node.fileRead(&out[0], 2, nbByte/2);
|
||||
node.fileClose();
|
||||
return out;
|
||||
}
|
||||
|
||||
static void write(const std::string& _path, const std::vector<int16_t>& _data) {
|
||||
etk::FSNode node(_path);
|
||||
if (node.fileOpenWrite() == false) {
|
||||
APPL_ERROR("can not open file : '" << node << "'");
|
||||
return;
|
||||
}
|
||||
node.fileWrite(&_data[0], 2, _data.size());
|
||||
node.fileClose();
|
||||
}
|
||||
|
||||
static void write(const std::string& _path, const std::vector<float>& _data) {
|
||||
etk::FSNode node(_path);
|
||||
if (node.fileOpenWrite() == false) {
|
||||
APPL_ERROR("can not open file : '" << node << "'");
|
||||
return;
|
||||
}
|
||||
node.fileWrite(&_data[0], 4, _data.size());
|
||||
node.fileClose();
|
||||
}
|
||||
|
||||
|
||||
int main(int _argc, const char** _argv) {
|
||||
// the only one init for etk:
|
||||
etk::init(_argc, _argv);
|
||||
std::string fbName = "";
|
||||
std::string micName = "";
|
||||
int32_t filterSize = 0;
|
||||
float mu = 0.0f;
|
||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||
std::string data = _argv[iii];
|
||||
if (etk::start_with(data,"--fb=")) {
|
||||
fbName = &data[5];
|
||||
} else if (etk::start_with(data,"--mic=")) {
|
||||
micName = &data[6];
|
||||
} else if (etk::start_with(data,"--filter-size=")) {
|
||||
data = &data[14];
|
||||
filterSize = etk::string_to_int32_t(data);
|
||||
} else if (etk::start_with(data,"--mu=")) {
|
||||
data = &data[5];
|
||||
mu = etk::string_to_float(data);
|
||||
} else if ( data == "-h"
|
||||
|| data == "--help") {
|
||||
APPL_INFO("Help : ");
|
||||
APPL_INFO(" ./xxx --fb=file.raw --mic=file.raw");
|
||||
APPL_INFO(" --fb Feedback file");
|
||||
APPL_INFO(" --mic Microphone file");
|
||||
APPL_INFO(" --filter-size Size of the filter");
|
||||
APPL_INFO(" --mu Mu value -1.0< mu < -1.0");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if ( fbName == ""
|
||||
|| micName == "") {
|
||||
APPL_ERROR("Can not Process missing parameters...");
|
||||
exit(-1);
|
||||
}
|
||||
APPL_INFO("Read FeedBack:");
|
||||
std::vector<int16_t> fbData = read(fbName);
|
||||
APPL_INFO(" " << fbData.size() << " samples");
|
||||
APPL_INFO("Read Microphone:");
|
||||
std::vector<int16_t> micData = read(micName);
|
||||
APPL_INFO(" " << micData.size() << " samples");
|
||||
|
||||
audio::algo::aec::Lms algo;
|
||||
if (filterSize != 0) {
|
||||
algo.setFilterSize(filterSize);
|
||||
}
|
||||
if (mu != 0.0f) {
|
||||
algo.setMu(mu);
|
||||
}
|
||||
std::vector<int16_t> output;
|
||||
output.resize(std::min(fbData.size(), micData.size()), 0);
|
||||
// process in chunk of 256 samples
|
||||
int32_t blockSize = 256;
|
||||
for (int32_t iii=0; iii<output.size()/blockSize; ++iii) {
|
||||
APPL_INFO("Process : " << iii*blockSize << "/" << int32_t(output.size()/blockSize)*blockSize);
|
||||
algo.process(&output[iii*blockSize], &fbData[iii*blockSize], &micData[iii*blockSize], blockSize);
|
||||
}
|
||||
write("output.raw", output);
|
||||
write("filter.raw", algo.getFilter());
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user