3#include "AudioTools/CoreAudio/AudioStreams.h"
4#include "AudioTools/CoreAudio/Buffers.h"
15template <
typename T =
int16_t>
26 size_t filter_len = 32,
float mu = 0.001f)
28 buffer_size(buffer_size),
29 filter_len(filter_len),
32 filter.resize(filter_len, 0.0f);
42 size_t write(
const uint8_t* buf,
size_t len)
override {
44 return ring_buffer.
writeArray((T*)buf, len /
sizeof(T)) *
54 size_t readBytes(uint8_t* buf,
size_t len)
override {
55 size_t read = p_io->readBytes(buf, len);
56 size_t actual_samples = read /
sizeof(T);
59 ring_buffer.peekArray(ref_vec.data(), filter_len);
60 for (
size_t i = 0; i < actual_samples; ++i) {
62 float echo_est = 0.0f;
63 for (
size_t k = 0; k < filter_len; ++k) {
64 echo_est += filter[k] * ref_vec[k];
66 float mic = (float)data[i];
67 float error = mic - echo_est;
70 for (
size_t k = 0; k < filter_len; ++k) {
71 filter[k] += adaptation_rate * error * ref_vec[k];
74 ring_buffer.
read(dummy);
76 for (
size_t k = 0; k < filter_len - 1; ++k) {
77 ref_vec[k] = ref_vec[k + 1];
79 ref_vec[filter_len - 1] = dummy;
88 void setLag(
size_t lag_samples) { lag = lag_samples; }
94 void setMu(
float mu) { adaptation_rate = mu; }
102 filter.resize(filter_len, 0.0f);
109 ring_buffer.
resize(buffer_size + lag);
110 for (
size_t j = 0; j < lag; j++) {
111 ring_buffer.
write(0);
113 filter.assign(filter_len, 0.0f);
123 float adaptation_rate = 0.01f;
124 Vector<float> filter;