Bug 447531

Summary: Please expose gain information of Opus files
Product: [Frameworks and Libraries] frameworks-kfilemetadata Reporter: Tobias Leupold <tl>
Component: generalAssignee: Pinak Ahuja <pinak.ahuja>
Status: REPORTED ---    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Tobias Leupold 2021-12-26 09:15:40 UTC
Hi KFileMetaData team :-)

Xiph.org says that Opus supersedes Vorbis (and the other lossy audio codecs as well). So it should be used for audio compression nowadays.

Currently, ReplayGain information is parsed for Vorbis files. The REPLAYGAIN_ALBUM_GAIN and REPLAYGAIN_TRACK_GAIN headers are put into KFileMetaData::Property::ReplayGainAlbumGain and KFileMetaData::Property::ReplayGainTrackGain, exposing the stored double value.

For Opus files, the gain information is currently not exposed. This seems to be a bit more complicated though, as Opus files seem to support at least two different approaches of storing gain information:

One is storing gain information in the R128_TRACK_GAIN and R128_ALBUM_GAIN headers. These are values calculatd by the EBU R 128 algoritm, represented as integers. To get the dB information, one has to divide this by 256. But the reference loudness value is different from the ReplayGain approach and – as far as I could grasp it – is 5 dB lower.

So either, one could parse this and expose it as KFileMetaData::Property::EBUR128[Album|Track]Gain or such, or add 5 dB and put it into the already existing KFileMetaData::Property::ReplayGain[Album|Tack]Gain. Which would probably be the easier way, as software using this would "just work" with Opus files this way without the need for additional code.

The other approach is storing the "Playback gain" in the stream header itself. This seems to be a double value, similar to e.g. R128_TRACK_GAIN/256.

What's a bit tricky about this is that this value seems to be applied automatically by backends, without control by the user. E.g. if I play an Opus file using Elisa that has R128_TRACK_GAIN set but not the Playback gain, nothing happens, it's just as loud as an Opus file without this information (or the same track encoded to Vorbis), because Elisa doesn't handle this information yet. On the other side, if I play the same track with the Playback gain header set, it's much quieter – apparently, the gain change is done inside the backend.

So, most probably, it would be meaningful to expose all three values, e.g. as

KFileMetaData::Property::EBUR128AlbumGain
KFileMetaData::Property::EBUR128TrackGain
KFileMetaData::Property::OpusPlaybackGain

so that software handling this can e.g. compensate the playback gain applied by the backend if no change is wanted, or adjust the volume according to the EBU R 128 level. Either by making the gain reduction 5 dB less, or lessen the gain reduction for ReplayGain header levels by 5 dB in addition, so that all files are played on the same level. At this point, I think that more information would be better here, as messing with those different values (if set) is not too hard, and one has more control knowing which values are actually set.

It would be really cool if you added this, so that e.g. Elisa could implement reliable handling of replay gain information. I'll also have a look into the code and see if I can contribure something to this. But I'm not sure if my coding skills are sufficient for that ;-) Thanks in advance for all work!

Cheers, Tobias