| Without dithering, the error (the difference between the ideal signal and the digital signal) is periodic, creating tones.
When you add a little bit of noise, this periodicity is broken up as you can see in the second image.
This tiny difference is enough to completely get rid of spurious tones!
You do lose a little bit of SNR in the process. RPDF costs around 3dB and TPDF around 4.8dB, but, your SFDR improves by 27dB for RPDF and 24dB for TPDF in this example.
So far, this assumes you have headroom to add fractional noise (+/-0.5LSB). But in many real systems, you don’t. An alternative is to make noise using a 1-bit PRBS (Pseudo Random Bit Sequence) and add that to your signal. This is a 1-bit signal where the probability of a 0 or a 1 is equal.
At the bottom of this email, I have python example code to generate a wav file with the 1kHz 8-bit signal from this demo. I used these WAV files to create the spectrum images (capture signal with a QA403 and process it in python to make the spectrum plots to for better images).
Best regards and happy designing,
Hans Rosenberg
P.S. I you want to learn more about electronics and you haven't seen my free mini-course on Electromagnetic PCB Design yet, you can get access here: https://www.hans-rosenberg.com/minicourse_account_email?cid=24733e03-585f-4167-aa5b-6b71ee96c48b
This is the python program which generates the WAV files:
import numpy as np from scipy.io import wavfile import math as math
# SET SIGNAL PARAMETERS Fs=48000 # Sample rate F=1000 # signal frequency As=125 # signal amplitude time=300 #duration of signal in seconds dither=0 # 0=no, 1=RPDF, 2=TPDF
# Create the signal N=Fs*time t=np.arange(0,N) t=t*1/Fs signal=np.sin(2*math.pi*F*t); signal=signal*As
# combine them if dither==0: signal=signal elif dither==1: # This is Rectrangular Probability Density Function (RPDF) # RMS value is 0.5/sqrt(3) = 0.289LSB signal=signal+np.random.uniform(-0.5, 0.5, N) elif dither==2: # This is triangular Probability Density Function (TPDF) # RMS value is sqrt(2)*0.5/sqrt(3) = 0.408LSB (adding 2 uncorrelated noise sources) signal=signal+np.random.uniform(-0.5, 0.5, N)+np.random.uniform(-0.5, 0.5, N)
# Round to integers, critical not to use rounding to floor or ceiling, this will give distortion. signal = np.rint(signal).astype(np.int16) # Multiply to achieve full range signal = signal * 256
# create stereo signal stereo = np.stack((signal, signal), axis=-1) # L = R = mono signal # Make filename and write filename = 'signal256_0dither.wav' wavfile.write(filename, Fs, stereo.astype(np.int16)) |