Loudness Meters, Vertical track zooming and more ....

Hi folks,

Workin’ around I came to some ideas on ardour that could greatly improve the usefulness of this great program:

Loudness Meters
All bargraph meters on ardour seem to be of the PPM (Peak Program Meters) type, that is show at any time the instantaneous level of the signal. That is enough for many purposes, but kind of rough as measuring means for others. Some mastering prosumer equipment use a combined meter display, where you can look BOTH PPM and RMS measurings of the signal on the same BAR, something like: (-50)------------(-100)-----(0)------(6) XXXXXXXXXXXXXXXXXOOOOOOOO==============

Where X is a color painting RMS values and O is another color painting PPM values over the RMS value.

It’s true that an RMS value measuring dBFS doesn’t exactly mean loudness, but if you want to calibrate a mastering/monitoring system (say it for surround processing using SMPTE RP 200 level reference) with a sound pressure level meter in hand, using a fixed gain, the RMS value measured on dBFS on ardour outputs is linear on the RMS SPL at a fixed listening position, I mean dB(SPL)=k+dBFS where k is a constant depending on the gain chain and the position of the listener.

Track Waveform Vertical Zoom Factor
Ever tried to work on a signal recorded so softly that parts of it dont' show on the waveform? not even in the largest height view? You could say "well pal, go on, apply 12dB of gain on it, bounce and forget" ... But isn't ardour 'bout NON DESTRUCTIVE editing? Why should I need to alter anyway some original recorded track just to find that exact point where I want to cut a region or that spot that just works for doing a crossfade? Or what 'bout if I simply can't apply that gain cause dynamic range is too high and I'll end up clipping? The same way there is horizontal zooming, there should be track based Vertical zooming, this way you could zoom out vertically a track to work on soft passages on your tracks.
Track Waveform scale grid
When editing you often need to know what is the Peak/RMS value of pieces you're glueing together ... or perhaps have a global view on the peaks of a track without having to listen to the whole (what was it the peak level on that take 21.345 seconds ago?!?!?!?). Solutions for this could be:
  • Vertical Grid scale: One nice/simple approach on this would be to add a vertical grid with a level scale on the track waveform view.
  • Coloring Waveform\: another alternative approach (more complicated I guess) on the track waveform issue would be for instance to color the waveform based on intensity and add a color scale label somewhere ...
FFT Track View
Yeah, really, not kidding :) , I know this can be really hard to implement but would be marvelous. If you want/need/get curious 'bout the FFT view of your tracks you got to use external programs ... well, that could be ok if you need an FFT view of the master bus, what 'bout if you need FFT views of single tracks, just to know what spectra needs smoothing? where would be a nice place to apply a parametric EQ? You still could get on by attachin the track outputs to JACK app that provides the view you need ... ok, you're working with one track, that's ok ... what 'bout if you're working on the final mix of a 64track film soundtrack and you are in need of a spectral view of your tracks ("Oh bloody hell, where does that 13000hz .5 seconds long peak come from...")??? Spectral views are not a final solution for any problem, but give useful starting points to work them out, if you can take a look globally to the spectral contents of a track in one sight that could give you an idea of what to do with it to get your desired results.

… well, this are just some meditations on ardour and they don’t come from a sleepless boredom nite, this are issues that come from actually working with ardour.

keep the good work pals!


… it’s not about recording … it’s about freezing time!

Thanks for putting such an effort into this message. Let me answer all points:

RMS meters

It's an interesting idea. I will consider doing this, but there is a danger: peak computation is by far the most CPU intensive operation Ardour does. We have smart SSE routines to do very fast peak calculation, but it's still quite heavy. Adding RMS calculation, which is a lot more computation compared to the very easy "peak = max(abs(signal))" PPM computation, would be quite expensive CPU wise.

Vertical waveform zoom

With such low signals I thinks it's anyway a good idea to use the "normalize" function for regions. It's non-destructive and will apply "normalization gain" gain to the track enough so that the highest peaks will be at 1.0.

Track Waveform scale grid

This one I like. It could also be offered as a different view to a regions contents.

FFT Track View

At last someone who agrees with me! I think this is a good feature too. Actually in 2.0 there is already an fft analysis window (which you need to enable when building, see scons -h). The tool provides composite FFT analysis for either selected regions or ranges on selected tracks. It's not finished yet. Feedback is appreciated.

Well, about the FFT analysis window, I never managed to see where it could be activated/launched (from the GUI I mean, I did activate the build option)

Moreover, using 2.0 is difficult those days. The first alpha is just too old, and the current svn is badly broken due to the addition of several new features. is there a way with svn to grab older revisions ? The ones from 2 or 3 weeks ago seemed to work a lot better.

Marc-Olivier Barre,
Kinoko en Orbite

Hi, I’m glad my suggestions were well received,

If for RMS metering the problem is computation cost and you don’t have the physical time to work on it, perhaps with a couple of directions I might get a faster solution than brute forcing the RMS calculation … I’ll probably won’t be able to alter the classes myself cause I’ve never touched C++ but can go on an try several alternative ways to apporximate the RMS and find some low cost solution. If I find somethin’ I could provide you with the algorythm on plain ol’ kernighan & ritchie’s C (I’m a sinner … got tempted by the dark side, jumped directly from K&R C to Java last century) I could perhaps even hack a little JACK client as a proof of concept. I can’t promise anythin but know that I’ll be workin on this. (Besides I’d like to see if I can get an efficient way to do A or F weighted loudness calculations) I could contact you when/if I get some nice result … oh lord, it would be nice to do mental archeology and get back my C foo.
Just a couple of questions:

  • internal sample format is 32 bit float? (which raises the question ... why? as I understand recent pro processors use more than 48bit float to avoid artifacts on steep low pass filterings)
  • What are the classes responsable nowadays for peak calculations?

'bout the vertical zoom, just tried normalizing the region as you say, it works but if I have several takes, each on a separate region, I can’t do it cause peaks are not the same everywhere. Problem rose last sunday while I was glueing together two cantatas for lute and soprano, which means a dynamic range from plinky plinky lute to valkiria classed soprano shouting, these friends of mine never get to rehearse the whole cantatas so I had to glue them pieces (the cantatas, not my friends) , separate pieces which I can not normalize separately :frowning: … that’s when I’d love to have a vertical zoom.

I’ll try to compile Ardour2, I’m dying to see the FFT view! which are the options to give to scons for compiling the FFT view into? How can I access it from the UI?

greetings,

Sebastian.


It’s not about recording, it’s about freezing time …

Peak computation is not made in a class. It’s just a simple C / ASM function:

float compute_peak(float peak, long nframes, float *buf);

peak = previously computed peak
nframes = how many frames to calculate of…
buf = the signal buffer

I guess we would need to turn this into something like:

struct Peak { float PPM; float RMS; // Maybe some data gathered by the RMS algo in the previous run };

Peak compute_peak(Peak peak, long nframes, float *buf);

This function is called normally once per buffer, but as Ardour does sample-accurate events (automation, etc) we need the ability to divide a processing buffer to multiple parts. That’s why the previous peak data is needed.

Current peak computation algo is in libs/ardour/mix.cc compute_peak(), and the SSE assembly variant is in libs/ardour/sse_functions.s and sse_functions_64bit.s

Good luck!

Re: FFT analysis window

To make the tool to built in, you need to invke scons once “scons FFT_ANALYSIS=1”. Like all scons parameters, it will persist, so you need to give it to scons only once.

The tool appears in the either region or range context menus.

For regions: Select all the regions you want to analyze and right click on one of the regions. Go into the region submenu and find the entry “Analyze region”.

For ranges: Select the range(s) you want by dragging the range tool, to add more ranges shift-drag the range tool. Then select the tracks you want by ctrl-clicking on the track headers, you’ll see which tracks are selected as the ranges will appear on all selected tracks. Then right click on one of the ranges and select the range submenu and the entry “Analyze range”.

You can use this command to retrieve previous versions of ardour 2.0.

svn update -r[revision]

What sort of issues are you having with the recent revisions?

btw. See my answer to the original poster for details on how to use the FFT analysis window

Hi there,

As I’ve been searchin’,RMS^2 can be computed accurately (with no need of memory for previous values or frames but just the prior RMS^2) doing 2 divisions and 3 multiplications per each frame in the buffer plus a log per dbFS value required … that is for computing instant rms values of a 1024 frames buffer you need a total of 21024 divisions and 31024 multiplications and just 1 log for each time you want a dBFS value, say if you need a single dbFS RMS value representing the whole buffer you need to evaluate just one log, you need two you should evalute two log. That’s not that heavy … but a lot of multiplications anyway. The divisions could be precalculated and reused for all dBFS calculation (sacrifying a buffer size to store them).
The logarithm on the other side could be tore down to an efficient binary log with just enough precission as needed.

The idea is using time averaging, a statistics method wich measures accurately the standard deviation of a popolation minimizing the calculations per frame. You could even (adding another two multiplications) compensate at each frame for DC offset :slight_smile:

I’ve finished my jack_rms_meter but want to try out the binary log and the precalculated divisions before throwin’it to the wild.
Any interest on my tiny C client? should I post it somewhere?

… i know I’m rediscovering hot water, but this could be of some use. At least for me, it is!


It’s not about recording, it’s about freezing time …

Post your source somewhere, anywhere, maybe on this forum or maybe you have access to a more appropriate site. But one piece of advice: when you post it, please post it with the licence (I’m hoping GPL) you select for the code.

Hi there,

This is the tiny JACK client I wrote for RMS calculations (off course GPLed), it will eventually find somewhere nicer to get published (sourceforge, I guess).

http://www.webalice.it/rotoquezada/jack_loudness_meter.tar.gz

Once launched it will drop to STDOUT lines containing RMS, RMS (DC corrected), PEAK and DC OFFSET of the signal at its input port.
The readout rates are hardcoded in main.c as 4 readouts a second, DC offset window length sample_rate. For decent transformator isolated audio signals DC OFFSET should be zero so for each frame in ardour you should actually just compute the square time average and not the time variance.

The important thing on this client is the concept of “Time Averaging”. Calculating averages over N values can be accomplished using just the actual sample, the prior average and the sample number as:
AVG(N)=X(N)/N + AVG(N-1)*(N-1)/N

If the statistical variable X(N) is the square of the sample value at N then the time average thus calculated corresponds to the square of the RMS value. This is how RMS values are calculated on my client.

If we’re talking 'bout DC corrected RMS computing, a more adecuated estimator would probably be the Time Variance over the window which can be evaluated using:

VAR2(N)= VAR2(N-1)*(N-1)/N + (X(N)-U(N))^2/(N-1)

Where X(N) is the sample value and U(N) it’s time average.
This is how DC corrected RMS values are calculated on the client.

In order to improve performance divisions are precalculated and stored in a table of size sizeof(float)*max(samples_per_readout,samples_per_dc_readout)

Logarithms are replaced by a quick approximation which uses some multiplications, anyway you compute the logarithm just when you want a readout, not for every frame. These Logarithm approximations are fast, but attention! they work just on IEEE 754 32 bit floats!

This ugly client (sorry … it’s been a while since I wrote some C stuff) will get better in time, I plan to add A weighing to measures and a variable offset to represent the gain chain between JACK and the measure microphone.

Hope it’s useful enough as a proof of concept. It served me as a good excuse to learn some JACK programming and as soon as I get my sonometer
I’m trying to further develope this meter.


It’s not about recording, it’s about freezing time …

i second the “Track Waveform scale grid” or something similar that shows at least a -INF.db center [opaque] line and maybe a -6db [opaque] line as well, in the waveform itself -per channel of course.

I’d really like to see RMS and possibly subjective loudness (e.g. Zwicker, Stevens) metering options too.

Also, could I suggest a “waveform” display for the Tracks window that’s based on the signal level (e.g. RMS level or subjective loudness) instead of the raw waveform? This would be more compact because it wouldn’t have to deal with negative values, and could use a dB scale, which would make it much easier to make edits in quiet passages. You could use different colours to identify the peak, trough, and RMS regions.

As a bonus, such a display might make mastering engineers less concerned about maximising the loudness of all their recordings at the expense of sound quality! :slight_smile:

the signal level waveform display idea would be great! especially with a dB scale. the new program jokosher has a similar idea and it is very intuitive to look at. i think it is just a linear scale though. maybe ardour should have the two as an option?

the menu could be simply:

  • waveform display
    • normal
    • rms values
    • peak values
    • subjective loudness
  • waveform scale (i suppose this would be greyed out for the subjective loudness option?)
    • linear
    • logarithmic (dB)

I just want to put a vote in for vertical waveform zoom. Final Cut Pro has a similar feature, and it’s very useful when syncing different audio sources, even if they are quiet and should remain quiet (and un-normalized).