2
$\begingroup$

I am writing some software to benchmark an audio noise filtering method using SNR as an evaluation metric. One software component generates noisey audio by taking a clean audio file and a noise source file and simply adding the components. The clean file is usually longer, so the noise source is looped and/or padded to fill out all the samples.

I then pass this through my noise filter, getting a less noisey signal at the output.

How can I calculate SNR from the resultant data? My current method is to compute the RMS for the cleaned up signal and divide by RMS of the noise source giving the average power ratio. Is this the correct method?

Code is provided below:

float SignalCleaner::ComputeRMS(AudioFile<float> signal){
    float total_square = 0.0f;
    float n = (float) signal.getNumSamplesPerChannel() * (float) signal.getNumChannels();
    for(int channel_idx = 0; channel_idx < signal.getNumChannels(); channel_idx++){
        for(int sample_idx = 0; sample_idx < signal.getNumSamplesPerChannel(); sample_idx++){
            total_square += std::pow(signal.samples[channel_idx][sample_idx], 2);
        }
    }

    return std::sqrt(total_square / n);
}

float SignalCleaner::ComputeSNR(AudioFile<float> signal, AudioFile<float> noise){
    float signal_rms = ComputeRMS(signal);
    float noise_rms = ComputeRMS(noise);
    return 20 * std::log(signal_rms/noise_rms);

}

float SignalCleaner::SNRPreFiltered() {
    return ComputeSNR(noisey_signal, noise_source);
}


float SignalCleaner::SNRPostFiltered() {
    return ComputeSNR(output, noise_source);
}

Thanks, happy to provide further clarification

$\endgroup$
3
  • 1
    $\begingroup$ well, if you have the original noise-less audio, why don't you just subtract it from the output? $\endgroup$ Mar 17, 2022 at 18:44
  • 1
    $\begingroup$ @MarcusMüller: I second that. Care should be taken to time-align the filtered signal with the original one. $\endgroup$
    – Max
    Mar 18, 2022 at 11:12
  • $\begingroup$ Point taken, I will work on time-alignment next. However, for my own understanding, is there any reason my current method does not give an estimate for SNR? $\endgroup$ Mar 18, 2022 at 12:30

1 Answer 1

2
$\begingroup$

The current method proposed by the OP is flawed as it doesn't account for the possibility of signal losses in the filtering. This would require some sort of normalization, but once normalized then both powers would be the same and the ratio would be 1.

An optimum approach for computing SNR when a clean reference waveform is provided is to use the normalized cross-correlation between the two waveforms. The relationship between SNR and cross-correlation is further detailed in this post.

$\endgroup$
5
  • $\begingroup$ thanks for this, I now have an implementation yielding SNR from Pearson's correlation coefficient. Numbers look much more sensible. One follow-up question: Is it equally valid to compute the correlation between the signal (filtered or unfiltered) and the noise source array? How would this change the equation to convert rho to SNR? Many thanks! $\endgroup$ Mar 22, 2022 at 16:42
  • $\begingroup$ I am not sure what you mean by “noise source array”. Glad it is working for you. At higher SNR’s you will ultimately be limited by time offsets. I have implemented this with the ability to discern SNR’s exceeding 200 dB (I actually work with applications requiring that!) through high precision efficient resamplers. Message is to just be careful of this and measure your noise floor using two percent signals at varying sub-sample time offsets. $\endgroup$ Mar 22, 2022 at 16:54
  • $\begingroup$ Apologies, by array I mean samples. Due to the application I'm building, I would rather use the "noise source" signal samples over the "clean" ones for this computation. I'm wondering if I could instead compute the correlation using the noise source as reference and how this would change the conversion to an SNR score. $\endgroup$ Mar 22, 2022 at 17:03
  • $\begingroup$ Assuming the noise on each is independent, they would sum in power. If the SNR of the reference was 10 dB better than the SNR of your measured signal, the result would have 0.4 dB worst SNR than actual (found by adding the two independent noises in power). $\endgroup$ Mar 22, 2022 at 17:06
  • $\begingroup$ And my comment above was not intended to be “two percent signals” but “two perfect signals”! $\endgroup$ Mar 22, 2022 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.