Denormals and Ardour

What are they and why should you care?

Denormal refers to very small floating point numbers. Explanation on how this affects ardour will follow. More on denormals from: http://en.wikipedia.org/wiki/Denormal

The problem with denormals is that some processors (especially P4's but also some AMD processors) cannot calculate so small numbers without going into a special state. Switching between the normal and denormal state takes time. In effect this means that calculations done with denormals is very slow. Often in practice increasingly slow, which will eventually lead in audible glitches (xruns) and finally Jack kicking the slowed down client out of the processing chain.

Who's to blame?

Denormal issues in ardour are caused by plugins and despite legends floating around the internet, the plugin "host" (in this case Ardour) can't really do anything about it. Ardour can make sure that no plugin will get denormals in their input and that no plugin will output denormals, but sadly this isn't enough.

It is feedback in the plugin itself which causes denormal issues. Imagine a "perfect" feedback delay. In the delay, a fraction of the signal is always fed back to the delay. Imagine then a situation where the plugin is fed a signal where there is an impulse of some sort and followed by an infinite amount of digital black (0.00's). The impulse will circulate in the plugin forever, always getting fainter and fainter. In a floating-point DSP process, the impulse will eventually drop into the denormal range. All of this processing happens inside the plugin, thus Ardour can't affect the situation.*

In real day-to-day use denormal issues will strike in situations quite close to the previous one (but also in other situations as well). For example a region followed by no regions ("emptiness") on a track. The empty parts of the track are digital black while the region contains some signal. Playing through the region and into the empty zone will cause denormal unsafe feedback loops to start producing denormals. As the digital black will not add anything to the original signal in the feedback loop, the signal inside the plugin will eventually fall into the denormal range.

How to avoid them?

The only proper fix for this (short of changing your processor) is to either treat denormals as zeoes or add a dithering signal within the plugin.

Zeroing denormals is referred to as DAZ = denormals are zero. This means that all samples of the signal which are in the denormal range are treated as zeroes. In effect, zeroing them actually reduces a bit of noise in the process as the denormal range is below -200dB. That is way below what humans can hear. Especially since that level is also well below the limits of digital to analog converters. In other words: the electronical noise from even the best converter is many times louder than denormals.

Modern processors can be set to "DAZ" mode, which means that the processor will automatically treat denormals as zeroes. The programmer only needs to set this mode before the DSP math is done. This does not affect calculations done in the x87 FPU stack though, it only affects SSE and SSE2 operations.

The dithering method is the opposite. The idea is to add noise somewhere around -180 - -200 dB to the signal. That noise keeps the samples from ever going down to the denormal range, by adding that noise. Of course, it does add a bit of noise to the signal. But again, this noise is inaudible.

For the end-user, the answer to the question "How to avoid them?" is that the plugins need to be fixed. First you should check that you are using the most recent version of the plugin. If even the most recent release exhibits denormal issues, you should contact the author of the plugin.

* Ardour could feed a dithered "silence" instead of digital black in empty parts of tracks. The problem is: even though it could fix most of the denormal problems it still isn't a 100% fix for the issue. For example, if a plugin was to stop taking input (for example, input gain would be automated to -inf), feedback loops would still cause denormal issues.

Is there a list of CPUs that are immune or not affected as badly by denormals?

I’m not aware of such a list but I’ll keep an eye out for one. I’ll link or copy it here if I come across it.

Good idea though!

it’s possible to write an sse-based code, that’s using bitmasks to bash denormals / nans to zero …
i guess this is way faster than adding noise with block-based feedback systems…

what you write about the DAZ mode is only partially correct … on intel cpus the DAZ mode is only supported by the sse unit … so every floating point calculation on the fpu is still affected … and who knows, if all plugins are compiled to use sse code … so relying on this flag is not really safe …

Rebuilding all plugins with SSE (ie -mfpmath=sse) has eliminated denormal problems for me. That’s what I recommend to people; it’s at least worked for everyone who’s bothered to report back…

Thanks for pointing that out. I corrected the article.

I’ve read about the denormal problem as dicussed here. I’ve read the man page for gcc and it doesn’t seem to be any clearer.

In order to use -mfpmath=sse you need to have a CPU that supports full SSE (AMD Athlon-4,-xp, -mp, and 64-bit AMD’s).

In order to use -mfpmath=sse, you need (at least) -msse… But it appeasr you can have -msse2, -msse3 or -m3dnow.

I’ve always compiled the fftw libs (three times, for short, float, and long) with --enable-3dnow (which performs at least -m3dnow to GCC) …

Anybody with a moderm AMD should / could do the same when compiling for AMD?!?

CFLAGS="-mfpmath=sse" CXXFLAGS="-mfpmath=sse" ./configure --prefix=/usr --enable-3dnow […]

?? or perhaps even add -m3dnow to the FLAGS…

Thanks in advance!!

–Doug

on intel cpus the DAZ mode is only supported by the sse unit … so every floating point calculation on the fpu is still affected.In order to use -mfpmath=sse you need to have a CPU that supports full SSE (AMD Athlon-4,-xp, -mp, and 64-bit AMD’s. Free games

All plugins with SSE (ie -mfpmath=sse) has eliminated denormal problems for me. That’s what I recommend to people; it’s at least worked for everyone who’s bothered to report back…Term Paper

I have read the man page for gcc and it doesn’t seem to be any clearer.
In order to use -mfpmath=sse you need to have a CPU that supports full SSE (AMD Athlon-4,-xp, -mp, and 64-bit AMD’s).

dissertations