|
|
TITLE:: FluidLoudness
|
|
|
SUMMARY:: A Loudness and True-Peak Descriptor in Real-Time
|
|
|
CATEGORIES:: Libraries>FluidDecomposition
|
|
|
RELATED:: Guides/FluCoMa, Guides/FluidDecomposition
|
|
|
|
|
|
DESCRIPTION::
|
|
|
This class implements two loudness descriptors, computing the true peak of the signal as well as applying the filters proposed by broadcasting standards to emulate the perception of amplitude. It is part of the Fluid Decomposition Toolkit of the FluCoMa project.FOOTNOTE::This was made possible thanks to the FluCoMa project ( http://www.flucoma.org/ ) funded by the European Research Council ( https://erc.europa.eu/ ) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899).::
|
|
|
|
|
|
The process will return a multichannel control steam with [loudness, truepeak] values, both in dBfs, which will be repeated if no change happens within the algorithm, i.e. when the hopSize is larger than the server's kr period. More information on broadcasting standardisation of loudness measurement is available at the reference page FOOTNOTE::https://tech.ebu.ch/docs/tech/tech3341.pdf:: and in more musician-friendly explantions here FOOTNOTE::http://designingsound.org/2013/02/06/loudness-and-metering-part-1/::.
|
|
|
|
|
|
CLASSMETHODS::
|
|
|
|
|
|
METHOD:: kr
|
|
|
The audio rate in, control rate out version of the object.
|
|
|
|
|
|
ARGUMENT:: in
|
|
|
The audio to be processed.
|
|
|
|
|
|
ARGUMENT:: kWeighting
|
|
|
A flag to switch the perceptual model of loudness. On by default, removing it makes the algorithm more CPU efficient by reverting to a simple RMS of the frame.
|
|
|
|
|
|
ARGUMENT:: truePeak
|
|
|
A flag to switch the computation of TruePeak. On by default, removing it makes the algorithm more CPU efficient by reverting to a simple absolute peak of the frame.
|
|
|
|
|
|
ARGUMENT:: windowSize
|
|
|
The size of the window on which the computation is done. By default 1024 to be similar with all other FluCoMa objects, the EBU specifies other values as per the examples below.
|
|
|
|
|
|
ARGUMENT:: hopSize
|
|
|
How much the buffered window moves forward, in samples. By default 512 to be similar with all other FluCoMa objects, the EBU specifies other values as per the examples below.
|
|
|
|
|
|
ARGUMENT:: maxwindowSize
|
|
|
How large can the windowSize be, by allocating memory at instantiation time. This cannot be modulated.
|
|
|
|
|
|
RETURNS::
|
|
|
A 2-channel KR signal with the [pitch, confidence] descriptors. The latency is windowSize.
|
|
|
|
|
|
|
|
|
EXAMPLES::
|
|
|
|
|
|
|
|
|
code::
|
|
|
//create a monitoring bus for the descriptors
|
|
|
b = Bus.new(\control,0,2);
|
|
|
|
|
|
//create a monitoring window for the values
|
|
|
(
|
|
|
w = Window("Loudness Monitor", Rect(10, 10, 220, 65)).front;
|
|
|
|
|
|
c = Array.fill(2, {arg i; StaticText(w, Rect(10, i * 25 + 10, 135, 20)).background_(Color.grey(0.7)).align_(\right)});
|
|
|
c[0].string = ("Loudness: ");
|
|
|
c[1].string = ("Peak: ");
|
|
|
|
|
|
a = Array.fill(2, {arg i;
|
|
|
StaticText(w, Rect(150, i * 25 + 10, 60, 20)).background_(Color.grey(0.7)).align_(\center);
|
|
|
});
|
|
|
)
|
|
|
|
|
|
//routine to update the parameters
|
|
|
(
|
|
|
r = Routine {
|
|
|
{
|
|
|
b.get({ arg val;
|
|
|
{
|
|
|
if(w.isClosed.not) {
|
|
|
val.do({arg item,index;
|
|
|
a[index].string = item.round(0.01)})
|
|
|
}
|
|
|
}.defer
|
|
|
});
|
|
|
0.1.wait;
|
|
|
}.loop
|
|
|
}.play
|
|
|
)
|
|
|
|
|
|
//basic test, with default values
|
|
|
(
|
|
|
x = {var source = PinkNoise.ar(0.25);
|
|
|
Out.kr(b, FluidLoudness.kr(source));
|
|
|
source.dup;
|
|
|
}.play;
|
|
|
)
|
|
|
|
|
|
//free this
|
|
|
x.free
|
|
|
|
|
|
//the EBU standard specifies that the window should be 400ms long, and update every 100ms, for instantaneous loudness. At SR=44100, this means the following settings. Various test signals are loaded.
|
|
|
(
|
|
|
x = {
|
|
|
arg freq=220, type = 1, noise = 0;
|
|
|
var source = PinkNoise.ar(noise) + Select.ar(type,[DC.ar(),SinOsc.ar(freq,mul:0.1), VarSaw.ar(freq,mul:0.1), Saw.ar(freq,0.1), Pulse.ar(freq,mul:0.1)]);
|
|
|
Out.kr(b, FluidLoudness.kr(source,windowSize:17640,hopSize:4410,maxwindowSize:17640));
|
|
|
source.dup;
|
|
|
}.play;
|
|
|
)
|
|
|
// change the various frequencies to see the impact of the filter for the loudness. The TruePeak is steady.
|
|
|
x.set(\freq, 440)
|
|
|
x.set(\freq, 110)
|
|
|
x.set(\freq, 55)
|
|
|
x.set(\freq, 3000)
|
|
|
x.set(\freq, 9000)
|
|
|
|
|
|
// adding harmonics, by changing to triangle (2), saw (3) or square (4) shows that spectral algo are more resilient when signal are richer
|
|
|
x.set(\type, 2)
|
|
|
x.set(\type, 3)
|
|
|
x.set(\type, 4)
|
|
|
|
|
|
// adding noise shows its impact on loudness
|
|
|
x.set(\noise, 0.25)
|
|
|
|
|
|
// and removing the oscilator
|
|
|
x.set(\type, 0)
|
|
|
|
|
|
// and measuring silence
|
|
|
x.set(\noise, 0)
|
|
|
::
|