#include "SpeexDsp.h" #include #include SpeexDsp::~SpeexDsp() { close(); } void SpeexDsp::start(int sampleRate, int channels, int period) { close(); int frameSize = sampleRate * period / 1000; // 10-20 ms int filterLength = sampleRate * 500 / 1000; // 100-500 ms m_echoState = speex_echo_state_init_mc(frameSize, filterLength, channels, channels); speex_echo_ctl(m_echoState, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate); m_preprocessState = speex_preprocess_state_init(frameSize, sampleRate); speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_ECHO_STATE, m_echoState); int32_t noiseSuppress = -25, i = 1; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DENOISE, &i); speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); i = 0; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_AGC, &i); i = sampleRate; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); i = 0; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB, &i); float f = .0; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); f = .0; speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); } void SpeexDsp::close() { if (m_preprocessState != nullptr) { speex_preprocess_state_destroy(m_preprocessState); m_preprocessState = nullptr; } if (m_echoState != nullptr) { speex_echo_state_destroy(m_echoState); m_echoState = nullptr; } } void SpeexDsp::reset() { if (m_echoState != nullptr) { speex_echo_state_reset(m_echoState); } } void SpeexDsp::preprocess(int16_t *pcm) { if (m_preprocessState != nullptr) { speex_preprocess_run(m_preprocessState, pcm); } } void SpeexDsp::echoPlayback(const int16_t *play) { if (m_echoState != nullptr) { speex_echo_playback(m_echoState, play); } } void SpeexDsp::echoCapture(const int16_t *record, int16_t *out) { if (m_echoState != nullptr) { speex_echo_capture(m_echoState, record, out); } } void SpeexDsp::echoCancellation(const int16_t *record, const int16_t *play, int16_t *out) { if (m_echoState != nullptr) { speex_echo_cancellation(m_echoState, record, play, out); } }