[sdiy] 12 bit quantization noise, dithering, synths

brianw brianw at audiobanshee.com
Sat Feb 11 23:08:09 CET 2023


(sorry if this is a re-post for some of you - I didn't see the mailer send this one out before)

I'll start with something that may be obvious, but just in case:

You are adding the dither before you truncate to 12 bits, right?

i.e. Your FM engine calculates 24-bit samples (fixed point) or 32-bit samples (floating point), adds 2 LSB amplitude dither (where 2 LSB is relative to the destination 12-bit sample), and then truncates the result to a 12-bit value that feeds the DAC. You have to generate a digital signal with less noise before you can hope that dither will improve the S/N after truncating.


My second comment is about the on-board 12-bit DAC. I've stopped using DAC, and especially ADC, that is in the same chip as the CPU. There's simply too much digital noise from clocks and binary switching on the CPU to make for quality analog signal processing. Think of the massive amounts of current switching directions on every CPU clock cycle, and then think of what that does to the power rail and ground reference, and you can see why it can never be "quiet." As others have suggested, just use an external DAC - I don't think it even needs to be 24-bit, because 16-bit could be fine - and make sure that your PCB design keeps the analog supply voltages clean so that the analog signals will be clean. Standalone DAC chips are designed to keep the digital and analog signals separate, often such that all the digital pins are on one side, and the analog pins are on the other - you can even split the ground plane under the chip if you're from the school that understands how to properly segregate analog and digital planes.


Third, others have pointed out TPDF noise for dither. There's a paper from the AES that describes why this works so much better. Ideally, the noise source would have a Gaussian amplitude distribution. Computers most easily generate Uniform distribution, where every sample value is equal in probability. Gaussian distribution is expensive to calculate, though, and perhaps not worth the trouble. Adding two Uniformly distributed random numbers creates a TPDF, i.e., Triangular Probability Distribution Function (TPDF is not about distribution of frequencies in the noise, but about the distribution of the sample values in the time domain). A triangular histogram is just a first-order approximation of a Gaussian curve. You can get closer and closer to Gaussian by adding more Uniformly distributed samples, it just depends upon how fast you can run your RNG. At a minimum, you'll want two dither "samples" for every audio sample. In that sense, you're sorta oversampling, but really it's just using two Uniform random numbers to make a single TPDF number.


Fourth: Dithering can get fancier than the time-domain sample probability distribution by moving into the frequency domain. This is called noise shaping. As someone else pointed out, if the noise is all ultrasonic, then you won't hear it. If your sample rate doesn't reach ultrasonic frequencies, then you can use the Fletcher-Munson curve to shape the noise so it falls in the frequencies that we can't hear as well, while the frequencies that we hear the loudest are almost missing from the dither noise. Sometimes, though, just a simple, single-pole High Pass filter is close enough to the Fletcher-Munson curve to suffice.


My fancy DAC (Metric Halo Labs LIO-8 mkIV) has two Simple Dither options: TPDF, and TPDF Hipass. That's probably all you need to get passable quality from even as little as 8-bit DAC.


If you like, I can share links to some articles that talk about why the exact amplitude of the dither is important for removing audible quantization artifacts. These aren't easy papers to follow, though, unless you're really interested in the state of the art.

Brian


On Feb 10, 2023, at 12:05 PM, Chris McDowell wrote:
> I'm working on some FM synth code running on an STM32G431 (technically PM if you caught discussion a bit ago on this list) 
> For the most part, this chip is well suited to "chill" digital synthesis. I've got a handful of voices running 2 operator FM with feedback and loads of envelopes, all pretty satisfying. 
> I am using the built-in 12 bit DAC, and finally at the point where the quantization noise on the tails of long envelopes is bothering me. I have a very high-level understanding of what dithering is, and have played a little with naively adding a tiny bit of white noise to my output signal to mask the quantization noise. it DOES work, but the noise floor is really not that low, and I fear I'm misunderstanding some nuance of dithering here and kind of just caveman drowning it out with white noise. 
> 
> There's no issue besides on the tails of long envelopes. When we get close to silence, there is quite a bit of "hash" and digital goofiness that makes perfect sense given my implementation. 
> 
> To try to reduce the constant noise floor, I also tried adding the dithering to the envelopes instead of the output. this kind of works, but sounds a bit conspicuous. it's kind of just gating the quantization noise with the envelopes. I think it maybe sounds better than with no attention, but not really "better" than a constant bit of white noise underneath the signal. 
> 
> One question I have is: does my white noise sample rate need to be higher than my output signal's? 
> 
> But overall, my question to list is: what are some ways we can go about reducing quantization noise in 12 bit or lower outputs? 
> 
> Are there some subtle tricks or have I just never noticed 8 or 12 bit systems sounding, yknow, terrible... this could be a classic case of "yeah, listening hyper critically in a quiet room on nice headphones will reveal secrets sometimes", as the noise floor of my QSC PA speakers is actually quite a bit higher than this quantization noise, so I never realized it was there during less attentive testing. 
> 
> Cheers,
> Chris McDowell 




More information about the Synth-diy mailing list