FaceAccess/Record/SpeexDsp.cpp
2024-09-04 20:17:15 +08:00

78 lines
2.4 KiB
C++

#include "SpeexDsp.h"
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
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);
}
}