voice-engine / ec

Echo Canceller, part of Voice Engine project
GNU General Public License v3.0
240 stars 69 forks source link

Frame_Size should not be prime sizes #15

Closed StuartIanNaylor closed 4 years ago

StuartIanNaylor commented 4 years ago

Think you got it wrong way round as you seem to be setting the tail_length to powers of 2 whilst actually it doesn't matter but the FFT of the frame size you are dividing to give approx 10ms.

This often gives primes running at 16000 I have a choice of 128, 256, 512. 160 = 10ms but powers of 2 from testing work far better 256 hardcoded rather than the caculated 160 works noticeabilly better by quite a margin.

Prob needs a frame_size config option rather than calculating primes that don't work well with FFT

Change int frame_size = config.rate * 10 / 1000; // 10 ms

to

// int frame_size = config.rate * 10 / 1000; // 10 ms int frame_size = 256; // 10 ms

Make and try

xiongyihui commented 4 years ago

Does frame_size = 256 run faster? FFT window size may not be frame size. There is overlap between FFT windows.

|------ 10 ms -------|------ 10 ms -------|------ 10 ms -------|------ 10 ms -------|
|------------ FFT window 1 ---------|
                     |------------ FFT window 2 ---------|
                     |----overlap---|

I may get it wrong.

StuartIanNaylor commented 4 years ago

Hi xiongyihui your EC app is great and dunno but reading the Speexdsp manual.

It is recommended to use a frame size in the order of 20 ms (or equal to the codec frame size) and make sure it is easy to perform an FFT of that size (powers of two are better than prime sizes).

https://www.speex.org/docs/manual/speex-manual.pdf

I think it does slightly its hard to tell as going off audible results. I think the filter_length (tail_length) doesn't matter so much from the manual and noticed you seem to use 2^ there when maybe it should be the frame_size 128/256?

PS your EC app works great as the ALSA implementation of speexdsp is awful as not sure what it does to get things so wrong when yours works. On the Pi or Arm though we are hitting a problem as more use a 64bit OS as speexdsp doesn't compile and complains about 8bit Integers being missing. In fact I have a Cortex-A35 CPU 64bit only Rockchip that was gutted I couldn't compile and get it to work well as normal, Pi4 is same but the slower 32bit OS still has the faster neon support with speexdsp. Which is weird as Neon64 supports 16bit but if you enable neon with the speexdsp ./config it errors but 32bit compiles OK.

Two 64-bit, four 32-bit, eight 16-bit, or sixteen 8-bit integer data elements can be operated on simultaneously using all 128 bits of a Neon register. Two 32-bit, four 16-bit, or eight 8-bit integer data elements can be operated on simultaneously using the lower 64 bits of a Neon register (in this case, the upper 64 bits of the Neon register are unused).

https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/neon-programmers-guide-for-armv8-a/introducing-neon-for-armv8-a/single-page On 64bit you can compile without --enable-neon but obviously that is much slower.

I have tried leaving mails on the dev group of speex but it seems inactive or not interested. My C is non existant but maybe you could have a look or send them a message why and how to support 64 bit?

Many thanks

PS just looking at that manual.

If you wish to further reduce the echo present in the signal, you can do so by associating the echo canceller to the preprocessor (see Section 6.1). This is done by calling: speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE,echo_state); in the initialisation.

Is that done or tried? I thought they had seperated them so not sure how that works, but if it does as currently it works well but there is a residual echo left but the source audio is near perfect. If it 'vocodes' like the pulse_audio webrtc seems to then no as on the Pi it seems to totally remove echo but creates much distortion with the non-echo source.

StuartIanNaylor commented 4 years ago

They prob just need to add this as a lib. https://projectne10.github.io/Ne10/doc/index.html

https://github.com/linto-ai/gpu-ne10-mfcc

StuartIanNaylor commented 4 years ago

Doh!

https://gitlab.xiph.org/xiph/speexdsp/-/issues/1