When and to what should I apply dithering?
Reply #6 – 2013-03-30 09:39:44
Thanks everyone. This clears a few things up. Just a few details:And on a related matter, if currently only one signal is active (meaning nothing gets mixed), and it's not been attenuated at all (meaning having a volume factor of 1.0), is dithering still needed? Yes if you resample or if output bitdepth is less than the signal bitdepth. Does it matter that resampling happens at 32-bit float? And does the quality of the resampling affect the decision? I support different resamplers as back-ends (SRC, Speex from Opus-tools and SoXR). For example, if I resample a 32-bit float signal using SRC_SINC_BEST_QUALITY, then convert it to 24-bit integer, would I need to dither because of the resampling? (Since according to the other advice, converting to 24-bit doesn't need dither.)Please watch this Xiph video esp. the chapters on bit depth and dithering . Don't dither when going from 32-bit floats (which have 24 bits of significand precision) to 24bit. 24-bit quantization noise is going to be inaudible with simple truncation. If you're giving 8-bit output, dither will probably be vital to avoid annoying distortions. For 16-bit output it's a toss-up. I suppose it doesn't matter that I don't actually truncate bits, but actually do a full rescale to the target bit depth? My current implementation is this:/* Convert and clip a float sample to an integer sample. This works for * all supported integer sample types (8-bit, 16-bit, 32-bit, signed or * unsigned.) */ template <typename T> static void floatSampleToInt(T& dst, float src) { if (src >= 1.f) { // Overflow. Clip to max. dst = std::numeric_limits<T>::max(); } else if (src < -1.f) { // Underflow. Clip to min. dst = std::numeric_limits<T>::min(); } else { dst = src * (float)(1UL << (sizeof(T) * 8 - 1)) + ((float)(1UL << (sizeof(T) * 8 - 1)) + (float)std::numeric_limits<T>::min()); } } Would you recommend truncation instead? (I assume that this means converting to 32-bit integer first, and then drop the low-order bits that don't fit.) Edit: Btw, thanks for that video! Seeing the concepts visualized well goes a long way in better understanding them.