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);
63 cancel(data, play_buf.data(), data, actual_samples);
72 void setLag(
size_t lag_samples) { lag = lag_samples; }
78 void setMu(
float mu) { adaptation_rate = mu; }
86 filter.resize(filter_len, 0.0f);
93 ring_buffer.
resize(buffer_size + lag);
94 for (
size_t j = 0; j < lag; j++) {
97 filter.assign(filter_len, 0.0f);
107 void cancel(
const T* rec,
const T* play, T* out,
size_t len) {
108 for (
size_t i = 0; i < len; ++i) {
110 ring_buffer.
write(play[i]);
114 ring_buffer.peekArray(ref_vec.data(), filter_len);
116 float echo_est = 0.0f;
117 for (
size_t k = 0; k < filter_len; ++k) {
118 echo_est += filter[k] * (float)ref_vec[k];
121 float mic = (float)rec[i];
122 float error = mic - echo_est;
126 for (
size_t k = 0; k < filter_len; ++k) {
127 filter[k] += adaptation_rate * error * (float)ref_vec[k];
139 float adaptation_rate = 0.01f;
140 Vector<float> filter;