public void InitAEC() { lock (this) { if (disposed) { return; } playFramer = new Voice.Framer <float>(frameSamples * playSamplingRate / samplingRate * playChannels); InitPlayDelay(AECPlaybackDelayMs); int filterLength = samplingRate * AECFilterLengthMs / 1000; DestroyEchoState(); stEcho = speex_echo_state_init_mc(frameSamples, filterLength, channels, playChannels); speex_echo_ctl(stEcho, SPEEX_ECHO_SET_SAMPLING_RATE, ref samplingRate); speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, stEcho); logger.LogInfo("SpeexProcessor AEC: create sampling rate {0}, frame samples {1}, filter length {2}ms={3}frames, mic channels {4}, out channels {5}, playback delay {6}ms={7}:{8}frames", samplingRate, frameSamples, AECFilterLengthMs, filterLength, channels, playChannels, AECPlaybackDelayMs, playDelayFrames, playDelayMaxFrames); logger.LogInfo("SpeexProcessor AEC: output sampling rate {0}", playSamplingRate); if (playSamplingRate != samplingRate) { logger.LogWarning("SpeexProcessor AEC: output sampling rate {0} != {1} capture sampling rate. For better AEC, set audio source (microphone) and audio output samping rates to the same value.", playSamplingRate, samplingRate); } } }
private void InitReverseStream() { lock (this) { if (!aecInited) { if (disposed) { return; } int size = processFrameSize * reverseSamplingRate / samplingRate * reverseChannels; reverseFramer = new Voice.Framer <float>(size); reverseBuf = new short[processFrameSize * reverseChannels / channels]; // should match direct stream if (reverseSamplingRate != samplingRate) { logger.LogWarning("WebRTCAudioProcessor AEC: output sampling rate {0} != {1} capture sampling rate. For better AEC, set audio source (microphone) and audio output samping rates to the same value.", reverseSamplingRate, samplingRate); } aecInited = true; } } }