Zero Cross Rate VAD
Hi,
I am currently working on two noise reduction algorithms. One for background noise and one for non-stationary noise. The background noise algorithm is finished. For the none stationary noise I wanted to use a VAD. The VAD block from SigmaStudio does not function properly with non-stationary noise. I created a Zero Crossing Rate(ZCR) detector to classify frames as speech or noise.
The idea is to measure the zero crossings for a frame of 20ms. If the frame contains more than 25 zero crossings it will be classified as noise and it will not be routed to the output of the DSP. What I have implemented now is shown in the figure below.
It measures the zero crossings and routes the signal with 20ms delay to the output if it is speech. The ZCR "works". Speech is routed through and noise is classified as noise, however the noise is not classified as noise when the Max & Hold is reset. During the reset the rate is 0 and the noise is routed to the output causing a stutter.
The Yellow signal is the output of the DSP. It is a noise only signal. The Blue signal is the Max & Hold. As you can see when the Max & Hold is reset the noise signal passes though for a brief period.
I want to create a buffer of 20 ms if it is possible, count the ZCR during 20ms and multiply the buffer by 1 or 0 for speech and noise respectively.
EDIT:
I changed the schematic to hold the value at the end of the frame just before the reset. Compare it to the threshold and let a 0/1 pass accordingly, use Hold blocks with a inverted timer to hold the 0/1 for 20 ms and multiply it by the delayed signal. This is on an ADAU1761. The project is attached, it works but not well. It seems some parts of the noise have the same number of ZC as the speech signal. The test signal is also attached.
Audio Signal Processors
SigmaDSP Audio Processors
adau1761
Adding an Envelope Peak smooths out the classification greatly. The VAD now works alright for the type of noise
of the signal.
Here are some images of the results of the ZCR VAD. Below in each image are the clean speech signal, the speech + friction noise of the mic and the output of the ZCR from top to bottom respectively.
As can be seen in the image below, the VAD performs fine with medium level noises.
With higher level noises the VAD cuts of sections of speech. Maybe an adaptive ZCR threshold
could be implemented that changes with signal level.
For noises like white noise or pink noise the VAD works very good. It detects speech in signals
with a SNR of up to -20dB, of course the speech at those levels are almost inaudible.
This is really great stuff using the Sigma Studio blocks. May I ask how you generated the speech plots? I really like how you demonstrated the last one with the red/blue color differentiation.
Hi Simon,
Thanks, I have improved the algorithm a bit with a compressor etc. The plot are generated from in Matlab. I made some custom scripts to measure the SNR etc. But these are just plots of the time data. You can also make them in GNU Octave, it's like the free version of Matlab.
Adding a 1 Hz 1st order low pass filter in the VAD behind the frame hold greatly improves the VAD. It's detection is a lot smoother. Also adding two threshold with hysteresis greatly improves switching between microphones. This prevents constant switching between microphones and false detection.
The image below shows the slewing of the attack and decay of the ZCR by the low pass filter.
Also because the signal is 1 Hz it can be monitored perfectly in the real time graph. Settings threshold is a lot easier now.
Please log in to reply.














