Subject: [codec] draft-ietf-codec-oggopus: R128_TRACK_GAIN units

From: Mark Harris <[email-masked]>
Date: Mon, 8 Sep 2014 10:09:49 -0700

The tags R128_TRACK_GAIN and R128_ALBUM_GAIN are specified by
draft-ietf-codec-oggopus-04 to contain a level adjustment as a fixed
point Q7.8 value; i.e. in the 1/256 LU units that are used in the
output gain field of the Ogg Opus header.  Is it expected that these
units would be adopted by other codecs?

Because tags are most often used for codec-independent metadata such
as TITLE and ARTIST, code to handle them is often shared between
formats and they may be copied when transcoding or remuxing.  I am
concerned that if Ogg Opus uses 1/256 LU units, and another format or
codec uses the much more obvious LU (dB) units, then someone may be in
for a jolt (or almost complete silence) when their player interprets a
value intended to be in 1/256 LU units as being in standard LU units.

Because there is an existing nearly universally used standard unit, it
would seem to be much better to use that unit in tag values,
especially if the value is a string with no units, in order to
minimize the chance that the wrong units will be used and reduce
confusion for people who are viewing or editing the text tags or
converting or comparing with standard ReplayGain tags.  It should not
be necessary to be an expert on the Ogg Opus specification in order to
be able to interpret the value of these tags, since there is no reason
for such information to be codec-specific or container-specific.

A related issue is the reference level.  The EBU R128 reference level
is -23 LUFS.  Prior to EBU R128 a -18 LUFS reference level was
commonly used, and there are other reference levels used in some
specific contexts.  Because the tag is used to normalize loudness of
audio from different sources, possibly using different codecs,
containers, and reference level standards, it would seem more sensible
to put the actual loudness measurement in the tag, and let the player
adjust it as needed to match the target loudness that it is using for
all audio sources.  In fact EBU R128 specifically recommends that
"Loudness Metadata shall correctly indicate the actual Programme
Loudness", not a gain adjustment.

In light of these issues, would it not be better to record a
TRACK_LOUDNESS tag in LUFS and an ALBUM_LOUDNESS tag (which would have
the same value for all tracks that are part of the album) also in
LUFS?

In order to allow a player to adjust the loudness to any desired
target loudness and dynamic range, ideally the loudness range and
maximum true peak level would also optionally be available in a
well-defined tag in order to allow the player to insert dynamic range
compression if necessary.

All of these tags should be codec-independent.

As specified by EBU R128, loudness, loudness range, and true peak
measurements should be made according to ITU-R BS.1770 and EBU Tech
3341.

 - Mark

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Mon, 08 Sep 2014 13:11:05 -0700

As an individual...

> units would be adopted by other codecs?

I can't speak for anyone else, but if _I_ were making a new codec, I 
wouldn't see a need to innovate here. This design has the lessons of 
doing this for 15+ years baked into it.

> codec uses the much more obvious LU (dB) units, then someone may be in

Then they should pick a different tag name.

> would seem to be much better to use that unit in tag values,

This was tried for ReplayGain tags. 1 dB units are far too coarse, and 
once you add a decimal point, people almost universally implement it 
incorrectly (due to various issues like atof and strtod having 
locale-dependent semantics, locale changes not being thread-safe in C, 
etc.). The choice here was a conscious one designed to avoid the 
failures of past mistakes.

It's also got two years of deployment at this point, so there's now 
non-trivial costs in changing it. If we had a good reason, we could 
change it. But "reduced confusion" is not a good reason. Changing now 
will only increase confusion (another lesson I've learned from letting 
people talk me into such changes in the past): people will be required 
to support both formats forever, despite the fact that one would be 
"standard" and the other wouldn't be.

> adjust it as needed to match the target loudness that it is using for

In a system with infinite dynamic range, sure. In a system without that 
(like, say, the fixed-point decoder provided in the reference 
implementation), starting from a 0 LUFS reference means naive 
implementers will introduce substantial clipping distortions, and then 
later in the pipeline maybe they will make it quieter distortion. A good 
implementation will adjust downward during decoding, before clipping 
occurs. Baking a good default adjustment into the reference (as _all_ 
loudness measurements have some reference... there's no concept of a 
loudness measurement that doesn't) makes the naive implementation into a 
good implementation. Baking in anything other than the R128 recommended 
reference level would, as you like to say, cause confusion.

> Loudness", not a gain adjustment.

And that is what the current values already represent. If it makes you 
feel better to think of the offset of 18*256 as a detail of the encoding 
in this file format, then go ahead.

> the same value for all tracks that are part of the album) also in

I think it would be worse, for all of the reasons stated above.

> maximum true peak level would also optionally be available in a

I can't remember if it's been said on the list before, but "true peak" 
is a meaningless concept for a lossy format with a non-bit-exact decoder 
specification, like Opus. The variation in the true peak calculation 
depending on your decoder implementation is theoretically unbounded. So 
you're guaranteed the value going into this tag is garbage.

When we first drafted this spec, we also conducted a survey of all 
open-source software we could find that supported ReplayGain tags. 
Exactly 0 programs did anything sensible with the peak tags. The most 
sensible thing anyone did was ignore them, which fortunately was the 
majority of them. By leaving them out entirely, we're making it easy for 
people to do the right thing.

The reference implementation includes a 0-delay declipping function, 
opus_pcm_soft_clip(). It's run by default when decoding to 16-bit 
integer output. You can call it yourself if you decode to float and 
convert to 16-bit later (as libopusfile does by default). If you don't 
clip, it has zero impact on the decoded output.

It's an excellent choice for those who want to handle clipping without 
adding any more complexity to their decoding pipeline. Maybe it's 
possible to do better by adaptively enabling DRC and using a 
sophisticated reconstruction declipper like the one Monty wrote for 
Postfish, but anyone who can set that up properly would have been one of 
the smart ones who ignored the peak tags to begin with.

---

From: Calvin Walton <[email-masked]>
Date: Thu, 11 Sep 2014 12:00:39 -0400

> Then they should pick a different tag name.

Just to comment on this:

The format of the "vorbiscomment" fields is very similar between at 
least Ogg Vorbis, FLAC, and Ogg Opus. As a result, the tags are often 
copied verbatim between the three formats during transcoding, and the 
interpretation of tag meaning based on name is usually shared between 
all three codecs in parsing code.

As a result, without explicit code in the parser to e.g. reject or 
interpret differently this tag between different formats, a player 
that implements the R128_*_GAIN fields will as a side-effect add 
support for the same tag in FLAC and Ogg Vorbis.

(This is the same reason that some players - at least gstreamer-based 
players, rockbox, and foobar2000 - currently accept and use 
REPLAY_GAIN tags in Ogg Opus files)

Since this tag format is defined/specified in the Ogg Opus 
specification, it might make sense to use a prefix on the tag name - 
e.g. OPUS_R128_TRACK_GAIN - if the intent is that this tag is to be 
used only in the Ogg Opus format. This would reduce the likelihood of 
conflicts in the mostly-unregulated vorbiscomment namespace.

If the intent is that the R128 tags are intended to be used also in 
FLAC and Ogg Vorbis then I think it would be best for it to be defined 
outside of the Opus specification, somewhere that developers can 
reference independently. In particular, care would be needed to 
describe interactions with the REPLAY_GAIN tags that are still used in 
these other formats.

-- 
Calvin Walton <[email-masked]>

---

From: Ron <[email-masked]>
Date: Fri, 12 Sep 2014 03:27:42 +0930

> REPLAY_GAIN tags in Ogg Opus files)

This is of course one of the perils of people implementing 'generic'
code with no sanity checking.  I believe there are libraries which
will happily try to force almost any codec into almost any kind of
container, whether that is well defined and well behaved or not.

Code reuse is great.  Code without sanity checking gets to keep
all the pieces.  There's not much we can do about that except
continue to remind people of the damage that blind application of
the 'be liberal' principle does.

Which isn't to say that FLAC and Vorbis and other Ogg mappings
shouldn't ever recognise these tags, but that's a discussion for
somewhere other than here right now.  This group isn't responsible
for decisions relating to those, nor have we been asked to be.

> describe interactions with the REPLAY_GAIN tags that are still used in 

I think Tim already covered this when he said:

    It's also got two years of deployment at this point, so there's
    now non-trivial costs in changing it. If we had a good reason,
    we could change it.  But "reduced confusion" is not a good
    reason. Changing now will only increase confusion (another
    lesson I've learned from letting people talk me into such
    changes in the past): people will be required to support both
    formats forever, despite the fact that one would be "standard"
    and the other wouldn't be.

There's no inherent reason these tags need to remain Opus specific,
this is just the first place they've been defined.  If nothing else
ever picks them up, that's probably not a big deal, if other things
do, they can copy or reference the definition here, just as we have
referenced the VorbisComment specification.

  Ron