I am trying to show with numpy that the quantization noise of a sine wave matches the SNR formula of SNR = 1.761 + 6.02 * Q.
The numpy code is simple:
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")
When I look at the results, I get an SNR of 27.4dB for 3 bit of quantization. The theory predicts 19.8db.
Similarly, for 4 bits of quantization, I get an SNR of 36.1dB: ~9dB more than for 3 bits, where you'd a delta of 6dB.
Ultimately, I want to show how with 16 bits A/D conversion, you'd end up with 98dB, but as the quantization level increases, the output spectrum gets closer and closer to the input spectrum, which is a continuous downward slope, which raises the question at which point something is considered noise instead of part of the signal.
I used applied a hanning window to better isolate the sidelobes of the main signal, which, for 3 bits of quantization makes the SNR go up from the earlier 27.4dB to 33.3dB:
I'm trying to figure out where my understanding is lacking.
How can I numerically show demonstrate the validity of the 1.761 + 6.02Q theory?
Tom