正弦波量化信噪比不匹配 1.761 + 6.02 * Q

信息处理 噪音 信噪比 量化 麻木的
2022-01-10 18:18:54

我试图用 numpy 证明正弦波的量化噪声与 SNR = 1.761 + 6.02 * Q 的 SNR 公式相匹配。

numpy 代码很简单:


import numpy as np
import matplotlib
from matplotlib import pylab, mlab, pyplot
plt = pyplot

from pylab import *
from numpy import *
from scipy import signal

def quantization_noise(quant):
    N=8192
    freq = 128
    x = np.linspace(0., 1., N)

    y1 = 0.5 * np.sin(2 * np.pi * freq * x)

    y2 = (np.floor(quant * (y1)) / quant)
    diff = y2 - y1

    freqs = fftfreq(N)
    x_mask = freqs >= 0

    Y1 = np.fft.fft(y1)
    Y2 = np.fft.fft(y2)

    Y1db = 20 * np.log10(np.abs(Y1) / N * 4)[x_mask]
    Y2db = 20 * np.log10(np.abs(Y2) / N * 4)[x_mask]

    plt.plot(freqs[x_mask], Y1db, 'bx', label = "input")
    plt.plot(freqs[x_mask], Y2db, 'r-', label = "output")
    #plt.plot(freqs[x_mask], Y1db, 'bx')
    plt.ylim([-140, 5])
    plt.xlim([0, 0.5])

    snr = np.amax(Y2db[3*int(freq):])
    print(snr)

    plt.plot([0.0, 0.5], [snr, snr], 'm-.', linewidth=1.0)
    plt.text(0.3, snr+4, "SNR=%4.1fdB" % snr)

    plt.grid(True)
    plt.legend(loc=1)

if True:
    plt.figure(figsize=(10,6))
    quantization_noise(8)

    tight_layout()
    plt.savefig("quantization_noise_8.png")

    plt.figure(figsize=(10,6))
    quantization_noise(16)

    tight_layout()
    plt.savefig("quantization_noise_16.png")

当我查看结果时,我得到 3 位量化的 SNR 为 27.4dB。理论预测为19.8db。

在此处输入图像描述

同样,对于 4 位量化,我得到 36.1dB 的 SNR:比 3 位高约 9dB,而 3 位的增量为 6dB。

在此处输入图像描述

最后,我想展示如何使用 16 位 A/D 转换,你最终会得到 98dB,但是随着量化级别的增加,输出频谱越来越接近输入频谱,这是一个连续的下降斜率,它提出了一个问题,什么时候某些东西被认为是噪声而不是信号的一部分。

我使用了一个汉宁窗来更好地隔离主信号的旁瓣,对于 3 位量化,这使得 SNR 从之前的 27.4dB 上升到 33.3dB:

在此处输入图像描述

我试图找出我的理解不足的地方。

我如何用数字证明 1.761 + 6.02Q 理论的有效性?

汤姆

2个回答

这里的一些问题:

  1. 您的 SNR 公式仅适用于满量程正弦波,您的正弦波幅度为 -6dB,因此您的 SNR 将低 6 dB
  2. 该公式还意味着舍入,而不是截断,即另外 6 dB
  3. 您使用的频率是采样率的一个小整数除数,这意味着您只是一遍又一遍地重复相同的样本,并且没有获得足够的样本覆盖率来获得具有统计意义的结果。
  4. 您在频域中的 SNR 分析是不必要的复杂,并且容易出现不精确和掩蔽错误。直接在时域里做就行了。

这是在 Matlab 中的样子

%% quantization noise of a 16-bit sine wave
fr = 975.3; % something odd
n = 8192;
quant = 2^15;
% make the sine wave
y0 = sin(2*pi*(0:n-1)'/n*fr);
% quantize
yq = round(quant*y0)/quant;
% noise
yNoise = yq-y0;
% SNR
fprintf('SNR = %6.2fdB\n', 10*log10(mean(y0.^2)/mean(yNoise.^2)));

从技术上讲,您还必须解决正弦的正最大幅度可能削波的事实,但对于大量化而言,这没有有意义的区别。

编辑

回顾一下公式的来源以及它的实际含义可能会很好。这一切都始于量化噪声。如果我们量化和舍入比量化噪声均匀分布在之间,其中是量化步长。对于截断,它将均匀分布对于舍入,所得噪声功率为 [0.5δ,0.5δ]δ[0,δ]

Pround=δ212,Ptrunc=δ23

如果是位数,那么对于有符号信号,我们只需,因此我们得到 16 位舍入的噪声水平为Bδ=2B1

P16=23012101.1dB

对于具有合理广泛样本分布的任何信号都是如此。由于满量程正弦波的功率为,因此产生的 SNR 将为3dB98.1dB

我做错了很多,但我遗漏的关键是需要在整个奈奎斯特频谱上计算 SNR,而不是只看峰值。

这篇文章很好地解释了一切:从臭名昭著的公式中解开谜团,“SNR = 6.02N + 1.76dB”,以及为什么你应该关心

另一个问题是采样率是我的测试正弦波频率的整数倍。同一篇文章讨论了在评估真实 ADC 的性能时,这也是模拟域中的一个问题。可以通过稍微改变频率或向输入添加抖动噪声来避免这种情况。