I have a MATLAB code in which I need to calculate the SNR and SINAD of received signal at known frequency (assumed as tone signal). The issue is that sometimes the power at that frequency is lower than some of the spurs and distortion elements which may or may not have any relation at my desired frequency and the way that MATLABs SNR and SINAD functions work (AFAICT) are that they take the highest power level as the reference to which the SNR and SINAD is calculated resulting in erroneous results for my case.

Is there an workaround to this case so that I can get the exact SNR and SINAD for my frequency of interest without having to develop a custom code for it as MATLABs own implementation may be more reliable?


2 Answers 2


I use the correlation coefficient for very accurate SNR measurements when a reference test waveform can be used (or similarly if we know exactly what was transmitted and what the ideal signal characteristics are). For working with A/D converters where SINAD is also defined separately from SNR, this would be SINAD specifically since the result would be the signal power relative to the noise from all noise sources and distortions. More generally this can be referred to as the SNR as long as we’re clear that it is from all distortions and would also be consistent with EVM (Error Vector Magnitude) requirements. This is also an ideal and very accurate way to characterize noise figure in a receiver (better than using a broadband noise source as typically done when waveforms aren't known or available).

The relationship between SNR and the normalized correlation coefficient is given in this post with the formula to compute the correlation coefficient.

I call this the "Rho Tool" when I create one. Here is the detailed process:

  1. Create a data matched reference waveform as we would expect it to appear at the location in the receiver where the signal is captured. To accurately characterize radio or channel performance, the waveform must be done with randomly or pseudo-randomly assigned data so that the full occupied bandwidth is characterized. The waveform can be pseudorandom in that we can repeat for convenience of the measurement (time alignment below) but note that the result of the repetition over period $T$ will restrict the frequencies probed in the channel to be spaced at $1/T$ -- we want $1/T$ to be fine enough to capture all distortions as depicted in the frequency domain (such as a narrow frequency null) so slower repetition rate of test waveforms is better. Otherwise, you may get a good SNR for a specific waveform used for test that isn't representative of SNR's that would be achieved with other randomly generated waveforms.

  2. Remove all amplitude offsets by normalizing each waveform so that they have the same standard deviation.

  3. Remove all frequency offsets from the captured waveform (this is also done through correlation: the complex output of the cross-correlation function can be used as a metric of frequency offset)

  4. Remove all time offsets (again with correlation to get the two waveforms within one sample.)

  5. Provide precision timing adjustment with fractional resampling. This step is critical, and the fractional precision is driven by the dynamic range needed: I have created precision SNR measurements with dynamic range in excess of 100 dB using this approach which had motivated this question, a dynamic range I actually needed due to specialized applications, but such an SNR is beyond what would be needed in most situations! Doing this requires the ability to make really good fractional delay filter banks; for anything less than 100 dB dynamic range, I have had best success with least squares filter design to get there. As MattL concluded in the earlier link above, I use windowing approaches for higher SNR cases. As a guide, the limit of the SNR measurement will be $20log(2\pi/M)$ where $1/M$ is the fractional symbol delay achievable. So to get 100 dB as I have done, requires a filter bank with a precision of 1/16000! The group delay variation of the fractional delay filter has to be less than this phase variation $2\pi/16000$!. Luckily in most cases a 30 to 40 dB range would be more than sufficient and the fractional delay filter realization is simplified.

  6. The correlation coefficient is measured between the reference and captured waveform with time and frequency offsets removed and from that (as given in the link above, the SNR is determined). All time, frequency and amplitude corrections are optimized by sweeping those parameters while measuring SNR, and the minimum is found (giving the true SNR with no time / frequency / amplitude offset effects). I have done this efficiently using gradient descent with binary weighted steps (starting with the largest step size of half the range, probe to each side and choose the minimum, then reduced step by half and repeat, which finds the bottom in log2(N) steps, where N represents the number of total steps, which is the precision for each metric).

  • $\begingroup$ Thank you for the detailed answer. I'll definitely try to implement this as well $\endgroup$
    – malik12
    Apr 20 at 7:54
  • $\begingroup$ @malik12 It's a good exercise in what receivers have to deal with in terms of AGC, carrier recovery, timing recovery and good practice in making highly precision fractional delay filter banks (and use of them). The recovery tuning is all manual algorithmic search to find the bottom based on using the same SNR metric, so that's rather straightforward- the fractional delay filter part (if you need performance>30 dB) could take some specialized care to do it right. I recommend using group delay in the tools to evaluate the performance of your fractional delay filter, it gives the best visual $\endgroup$ Apr 20 at 12:57
  • 1
    $\begingroup$ I am adding a very important point about the reference waveform used... $\endgroup$ Apr 20 at 12:59
  • $\begingroup$ std is okay, it has specific weaknesses - example. An accurate reference can be crucial - if it can't be made reliably, the metric would be improved with workarounds. An idea to my mind is to use something like sparse_mean to attenuate outlier effects, which I used here, and better comparison domains like time-frequency. $\endgroup$ May 3 at 16:14

Apparently there is no way to get an accurate SNR or SINAD results with the built-in MATLAB functions for the case when your desired frequency (or bandwidth of interest) power is below that of the Interferences.

The only way is to develop a custom function to calculate the power of desired frequency components and then take ratio for SNR and SINAD calculations.

  • 1
    $\begingroup$ I do my computations for SNR using the normalized correlation coefficient with the reference waveform being careful to account for any time and amplitude offsets (also frequency offsets if the application results in that). Then I account for noise in distortion even at the same frequency (and phase distortion as well!). How do you distinguish between SNR and SINAD; I see that typically used to define the quality of an ADC but in general my concern would be SNR as capturing all distortion from the reference signal. $\endgroup$ Apr 5 at 2:29
  • $\begingroup$ @DanBoschen My rationale of using the FFT for SNR measurements was that the application basically used the FFT however your approach sounds interesting as well. Could you kindly elaborate what you mean by distortion 'even at the same frequency'. And if you have the time maybe you can post a detailed answer as my answer is just a No answer :) $\endgroup$
    – malik12
    Apr 18 at 9:34

Your Answer

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

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