Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: opusgain scanner implementation status (Read 10496 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

opusgain scanner implementation status

Recently I discovered a track in my portable collection (encoded with Vorbis AoTuV -q2), that had an audible artifact.

I checked and was able to ABX it vs the original at -q2 (104 kb/s) and -q3 (122 kb/s). I didn't check -q4 but it's possible that I can ABX it too.

Since all the hype is about Opus now, I tried the same track encoded with Opus at 96 kb/s and was unable to ABX it.

So I am now considering converting all my portable collection to Opus @96 kb/s to get better quality for similar or lower file size.
Two things are holding me back however:
  • Few Android players properly support the R128_xxx tags as described in the RFC section 5.1 "Output gain". For example GMMP, my previous player of choice, applies the mandatory output gain (actually the Android decoder applies it), but the R128 gain tag is ignored (confirmed by the GMMP author), although GMMP handles other replay gain tags correctly.
  • There is no official opusgain tool

So about that last point, why isn't there any opusgain tool in opus-tools, like vorbisgain in vorbis-tools?
Is it just lack of developer time, or is there a technical obstacle, a part of the Opus spec that is still moving?
Can we help develop it?

A list of possible implementations that could fit this need:

Does anyone know any other serious contender?

As a workaround I am currently using FFmpeg's ebur128 filter, and a bit a Python code to add R128 tags. I am thinking I could release a basic opusgain scanner based on this as a Python package, but requiring FFmpeg and Python as dependencies for such simple task is far from ideal.

EDIT: Fix links and typos.
Opus 96 kb/s (Android) / Vorbis -q5 (PC) / WavPack -hhx6m (Archive)

Re: opusgain scanner implementation status

Reply #1
::

+1 ... exactly my problem, I'm using GMMP too. Thank you for posting this!

Greetings, ...

::

Re: opusgain scanner implementation status

Reply #2
There is basic support for transferring REPLAYGAIN tags in FLAC files into Opus gains. This obviously has a bunch of issues, but it will get you gain tags in your Opus files.

Good audio tools such as foobar will also do gain calculations for you and apply the tags.

Not sure that helps much if your player ignores the tags!

An official opusgain tool isn't high on the list of priorities. Probably a third-party solution is going to happen first. The partially-written opusgain from git should be pretty close already, but hasn't been touched for years.

Re: opusgain scanner implementation status

Reply #3
* If you use ffmpeg to encode your files, REPLAYGAIN tags will be copied over.
* loudness-scanner supports scanning opus files and adding REPLAYGAIN tags to them.

Re: opusgain scanner implementation status

Reply #4
There is basic support for transferring REPLAYGAIN tags in FLAC files into Opus gains.
* If you use ffmpeg to encode your files, REPLAYGAIN tags will be copied over.
The Opus RFC explicitly discourages against this:
Quote
   To avoid confusion with multiple normalization schemes, an Opus
   comment header SHOULD NOT contain any of the REPLAYGAIN_TRACK_GAIN,
   REPLAYGAIN_TRACK_PEAK, REPLAYGAIN_ALBUM_GAIN, or
   REPLAYGAIN_ALBUM_PEAK tags, unless they are only to be used in some
   context where there is guaranteed to be no such confusion.
   [EBU-R128] normalization is preferred to the earlier REPLAYGAIN
   schemes because of its clear definition and adoption by industry.
   Peak normalizations are difficult to calculate reliably for lossy
   codecs because of variation in excursion heights due to decoder
   differences.  In the authors' investigations, they were not applied
   consistently or broadly enough to merit inclusion here.

Good audio tools such as foobar will also do gain calculations for you and apply the tags.

Not sure that helps much if your player ignores the tags!
Yeah I tried foobar2000 mobile on Android, and it handles the output gain header + R128 tags properly.
However it has its own set of flaws compared to GMMP (little possible customization compared to the foobar2000 on Windows that I remember, incomplete Bluetooth support, album arts sometimes not showing up...), which prevents me from labeling it as "good audio tool".

An official opusgain tool isn't high on the list of priorities.
Why is that? I am not familiar with the Ogg container format or the Opus codec internals, but using libebur128 + the vorbisgain code as a base, it does not strike me as very complex to implement. If all that is missing is some development time, I'd be happy to help (I write C/C++ code for a living).

* loudness-scanner supports scanning opus files and adding REPLAYGAIN tags to them.
Thanks, didn't know that one. Will try and report back.
Opus 96 kb/s (Android) / Vorbis -q5 (PC) / WavPack -hhx6m (Archive)

Re: opusgain scanner implementation status

Reply #5
I couldn't say why opusgain was not implemented along with the other tools. I imagine that it is considered a relatively niche (audiophile?) feature, although considerable effort was put into the design of the codec so that gains would be applied automatically by even the dumbest of decoders so it would have made sense to have a tool to make such files.

Just what is it you want to achieve? Switching from Vorbis to Opus because of one audible artefact seems excessive. You have no guarantee that Opus will not have an audible artefact at some point in some track. In fact I can almost guarantee it, given that there are known killer audio samples that Opus really struggles with. However, if you just want smaller files at an overall similar (or better) quality, then Opus would give you that.

Given the limitations of your Android decoder, do you want an actual compliant opusgain tool that will write tags that are useless to you? Or just something that will slam a gain into the header field? Or a tool that will write the traditional REPLAYGAIN tags into an Opus file? All these things are quite achievable, either based on vorbisgain (probably a clone rather than adding features into vorbisgain itself) or making opusgain work (since it seems to have everything in place, just not hooked up very well). I would add Deadbeef to the list of possible tools - I think at present it writes gain info into the old REPLAYGAIN tags although you might need the native Opus plugin rather than the ffmpeg version.

Re: opusgain scanner implementation status

Reply #6
Switching from Vorbis to Opus because of one audible artefact seems excessive. You have no guarantee that Opus will not have an audible artefact at some point in some track. In fact I can almost guarantee it, given that there are known killer audio samples that Opus really struggles with. However, if you just want smaller files at an overall similar (or better) quality, then Opus would give you that.
I agree that one single issue isn't an excuse to move to another codec.

Though in fact (and it's not matter of a point of view) Opus is not simply overall better than Vorbis/any other lossy coder at 96 kbps (and OP talks about this bitrate) but also  handles better difficult samples.  http://listening-test.coresv.net/s/scores_by_tracks_closeup_en.png
Look at scores (and amount of difficult samples ) where Opus and Vorbis struggle on difficult samples.
Also it's worth to mention that  the test  was very extensive  with 40 samples.

Re: opusgain scanner implementation status

Reply #7
* loudness-scanner supports scanning opus files and adding REPLAYGAIN tags to them.
Well it only writes RG tags, which the RFC strongly discourages for Opus files.

I couldn't say why opusgain was not implemented along with the other tools. I imagine that it is considered a relatively niche (audiophile?) feature, although considerable effort was put into the design of the codec so that gains would be applied automatically by even the dumbest of decoders so it would have made sense to have a tool to make such files.
I don't think it's a niche feature, and certainly not audiophile.
All I want is the volume of my tracks to be consistent when I'm playing them in my car or doing sport. That seem like a pretty common and mainstream need.
Even Apple has their RG/R128 equivalent with Sound Check.

Just what is it you want to achieve? Switching from Vorbis to Opus because of one audible artefact seems excessive. You have no guarantee that Opus will not have an audible artefact at some point in some track. In fact I can almost guarantee it, given that there are known killer audio samples that Opus really struggles with. However, if you just want smaller files at an overall similar (or better) quality, then Opus would give you that.
Your last sentence sums up what I want: "smaller files at an overall similar (or better) quality".
Of course I know no lossy codec can always be transparent, especially at such bitrates, and I should have given more context about the artifact.
I was playing a track (encoded by Vorbis) for the first time, so I has no knowledge of what the original track sounded like. I was in a noisy environment, with average quality in-ear earbuds. Despite that I noticed something was weird in the drum part (cymbal) of one part of the track. Back home I did an ABX test to compare with original lossless file and confirmed it was an audible encoding artifact.
Although I have done my fair share of ABX tests and I am somewhat trained to spot artifacts, I don't have exceptionally good ears, and I often fail to ABX most tracks during public listening tests.
I can accept that my portable collection has artifacts, but I can not accept that I am distracted by a "damn, was that not an encoding artifact?" feeling while listening to music.

Given the limitations of your Android decoder, do you want an actual compliant opusgain tool that will write tags that are useless to you? Or just something that will slam a gain into the header field? Or a tool that will write the traditional REPLAYGAIN tags into an Opus file? All these things are quite achievable, either based on vorbisgain (probably a clone rather than adding features into vorbisgain itself) or making opusgain work (since it seems to have everything in place, just not hooked up very well). I would add Deadbeef to the list of possible tools - I think at present it writes gain info into the old REPLAYGAIN tags although you might need the native Opus plugin rather than the ffmpeg version.
I am using foobar 2000 mobile for now, which is not perfect, but properly handles the R128_TRACK_GAIN tags.
I have reported the issue to the GMMP author, and he acknowledged it, and will fix it in the future, just not anytime soon because he is busy with a new major version and a R128 gain bug is not high on his priority list.
When he will fix it, I will switch back to GMMP (which I paid for).

To add the tags I am currently experimenting with small scripts with use FFmpeg ebur128 filter to calculate loudness, and Python Mutagen library to add tags.


Though in fact (and it's not matter of a point of view) Opus is not simply overall better than Vorbis/any other lossy coder at 96 kbps (and OP talks about this bitrate) but also  handles better difficult samples.  http://listening-test.coresv.net/s/scores_by_tracks_closeup_en.png
Look at scores (and amount of difficult samples ) where Opus and Vorbis struggle on difficult samples.
Also it's worth to mention that  the test  was very extensive  with 40 samples.
Interesting.
I though Opus, while still evolving, was already considered unconditionally superior to Vorbis at all bitrates.
Maybe I should just bump the Vorbis bitrate I am encoding with then.

EDIT: Sorry misread your message. Then one more reason to find/make an opusgain implementation and encode my collection to Opus.
Opus 96 kb/s (Android) / Vorbis -q5 (PC) / WavPack -hhx6m (Archive)

Re: opusgain scanner implementation status

Reply #8
* If you use ffmpeg to encode your files, REPLAYGAIN tags will be copied over.
I remember this happening for me in Madsonic. Yesterday I needed to completely reset my phone and now I see that Madsonic does not transfer the replaygain tags anymore.

The line used to convert is:

ffmpeg -i %s -f opus -acodec libopus -b:a 96000 -

Where %s is the input file. All files converted this way end up with a Opus header gain of +5.00 db according to fb2k. Before I distinctly remember the Opus header gain value being identical to the track replaygain value.

Have I gone crazy?

I've just tried this from the commandline, without Madsonic involved. Altough metadata is listed as being transferred, all the tags that are listed as "side data" are in reality not copied over.

Code: [Select]
C:\>ffmpeg -i pariah.flac -f opus pariah.opus
ffmpeg version N-81707-g11777eb Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.4.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-libebur128 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
  libavutil      55. 30.100 / 55. 30.100
  libavcodec     57. 57.101 / 57. 57.101
  libavformat    57. 50.100 / 57. 50.100
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 62.100 /  6. 62.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, flac, from 'pariah.flac':
  Metadata:
    disc            : 1
    HDCD            : 0
    TITLE           : Pariah (feat. Ninet Tayeb)
    DISCTOTAL       : 3
    VALID_BITS      : 24
    REPLAYGAIN_ALBUM_GAIN: -5.06 dB
    REPLAYGAIN_ALBUM_PEAK: 1.000000
    REPLAYGAIN_TRACK_GAIN: -5.10 dB
    REPLAYGAIN_TRACK_PEAK: 0.998708
    track           : 03
    ALBUM           : To the Bone
    ARTIST          : Steven Wilson
    GENRE           : Progressive Rock
    album_artist    : Steven Wilson
    DATE            : 2017
  Duration: 00:04:44.66, start: 0.000000, bitrate: 2525 kb/s
    Stream #0:0: Audio: flac, 96000 Hz, stereo, s32 (24 bit)
    Side data:
      replaygain: track gain - -5.100000, track peak - 0.000023, album gain - -5.060000, album peak - 0.000023,
[libopus @ 0000000002566420] No bit rate set. Defaulting to 96000 bps.
[opus @ 0000000002564e20] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, opus, to 'pariah.opus':
  Metadata:
    disc            : 1
    HDCD            : 0
    TITLE           : Pariah (feat. Ninet Tayeb)
    DISCTOTAL       : 3
    VALID_BITS      : 24
    REPLAYGAIN_ALBUM_GAIN: -5.06 dB
    REPLAYGAIN_ALBUM_PEAK: 1.000000
    REPLAYGAIN_TRACK_GAIN: -5.10 dB
    REPLAYGAIN_TRACK_PEAK: 0.998708
    track           : 03
    ALBUM           : To the Bone
    ARTIST          : Steven Wilson
    GENRE           : Progressive Rock
    album_artist    : Steven Wilson
    DATE            : 2017
    encoder         : Lavf57.50.100
    Stream #0:0: Audio: opus (libopus), 48000 Hz, stereo, flt (24 bit), 96 kb/s
    Metadata:
      encoder         : Lavc57.57.101 libopus
      DISCNUMBER      : 1
      HDCD            : 0
      TITLE           : Pariah (feat. Ninet Tayeb)
      DISCTOTAL       : 3
      VALID_BITS      : 24
      REPLAYGAIN_ALBUM_GAIN: -5.06 dB
      REPLAYGAIN_ALBUM_PEAK: 1.000000
      REPLAYGAIN_TRACK_GAIN: -5.10 dB
      REPLAYGAIN_TRACK_PEAK: 0.998708
      TRACKNUMBER     : 03
      ALBUM           : To the Bone
      ARTIST          : Steven Wilson
      GENRE           : Progressive Rock
      ALBUMARTIST     : Steven Wilson
      DATE            : 2017
Stream mapping:
  Stream #0:0 -> #0:0 (flac (native) -> opus (libopus))
Press [q] to stop, [?] for help
size=    3470kB time=00:04:44.67 bitrate=  99.9kbits/s speed=84.5x
video:0kB audio:3445kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.739028%
The resulting opus file does not have those tags and instead shows a Opus header gain value of +5.00db in fb2k.

Re: opusgain scanner implementation status

Reply #9
@gorman This may or may not be relevant. But your ffmpeg version is ancient (by ffmpeg standards).

I don't know how fb2k behaves. But everything seems to be working as expected here:

Code: [Select]
% ffmpeg -i t.flac t.opus
ffmpeg version N-86873-g9f449227a3 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.1.1 (GCC) 20170630
  configuration: --prefix=/usr --enable-gpl --enable-nonfree --enable-version3 --enable-avresample --enable-openssl --enable-libmp3lame --enable-libspeex --enable-libx264 --enable-libx265 --enable-libxvid --enable-libvpx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libfdk-aac --enable-libopus --enable-libsoxr --enable-libass --enable-libopenjpeg --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libwavpack --enable-libbluray --enable-frei0r --enable-shared --enable-pthreads --enable-pic --disable-static --disable-debug --enable-runtime-cpudetect
  libavutil      55. 69.100 / 55. 69.100
  libavcodec     57.102.100 / 57.102.100
  libavformat    57. 76.100 / 57. 76.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 95.100 /  6. 95.100
  libavresample   3.  6.  0 /  3.  6.  0
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, flac, from 't.flac':
  Metadata:
    ENCODER         : Lavf57.76.100
    REPLAYGAIN_ALBUM_GAIN: -12.54 dB
    REPLAYGAIN_ALBUM_PEAK: 1.000000
    REPLAYGAIN_TRACK_GAIN: -12.54 dB
    REPLAYGAIN_TRACK_PEAK: 1.000000
  Duration: 00:05:53.14, start: 0.000000, bitrate: 1764 kb/s
    Stream #0:0: Audio: flac, 48000 Hz, stereo, s32 (24 bit)
    Side data:
      replaygain: track gain - -12.540000, track peak - 0.000023, album gain - -12.540000, album peak - 0.000023,
Stream mapping:
  Stream #0:0 -> #0:0 (flac (native) -> opus (libopus))
Press [q] to stop, [?] for help
[libopus @ 0x558fecb5af00] No bit rate set. Defaulting to 96000 bps.
Output #0, opus, to 't.opus':
  Metadata:
    REPLAYGAIN_TRACK_PEAK: 1.000000
    REPLAYGAIN_ALBUM_GAIN: -12.54 dB
    REPLAYGAIN_ALBUM_PEAK: 1.000000
    REPLAYGAIN_TRACK_GAIN: -12.54 dB
    encoder         : Lavf57.76.100
    Stream #0:0: Audio: opus (libopus), 48000 Hz, stereo, flt (24 bit), 96 kb/s
    Metadata:
      encoder         : Lavc57.102.100 libopus
      REPLAYGAIN_TRACK_PEAK: 1.000000
      REPLAYGAIN_ALBUM_GAIN: -12.54 dB
      REPLAYGAIN_ALBUM_PEAK: 1.000000
      REPLAYGAIN_TRACK_GAIN: -12.54 dB
    Side data:
      replaygain: track gain - -12.540000, track peak - 0.000023, album gain - -12.540000, album peak - 0.000023,
size=    4125kB time=00:05:53.15 bitrate=  95.7kbits/s speed=47.2x
video:0kB audio:4094kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.749829%

Code: [Select]
% opusinfo t.opus
Processing file "t.opus"...

New logical stream (#1, serial: 56aa41e5): type opus
Encoded with Lavf57.76.100
User comments section follows...
        encoder=Lavc57.102.100 libopus
        REPLAYGAIN_TRACK_PEAK=1.000000
        REPLAYGAIN_ALBUM_GAIN=-12.54 dB
        REPLAYGAIN_ALBUM_PEAK=1.000000
        REPLAYGAIN_TRACK_GAIN=-12.54 dB
Opus stream 1:
        Pre-skip: 312
        Playback gain: 0 dB
        Channels: 2
        Original sample rate: 48000Hz
        Packet duration:   20.0ms (max),   20.0ms (avg),   20.0ms (min)
        Page duration:   1000.0ms (max),  997.6ms (avg),  160.0ms (min)
        Total data length: 4224125 bytes (overhead: 0.744%)
        Playback length: 5m:53.135s
        Average bitrate: 95.69 kb/s, w/o overhead: 94.98 kb/s
Logical stream 1 ended

Re: opusgain scanner implementation status

Reply #10
If anyone is interested, I have written a small command line r128gain scanner/tagger implementation to fill the lack of such tool.
Its written in Python and uses FFmpeg for decoding and R128 loudness analysis.

Highligths:
* writes tag using the ReplayGain format (follows ReplayGain v2 specification), or the R128_XXX_GAIN format as described in the Opus RFC
* should work with any file/tag format (my automated tests cover AAC, FLAC, Opus, MP3, Vorbis, WavPack)
* extremely fast (compared for example to vorbisgain) by using file based parallism and/or FFmpeg threaded decoding

I still have a few features to add before releasing a v1.0, but after a few weeks of testing with different file formats, both as a command line tool and a library for some of my projects, it seem to work quite well.

It's not a lot a code and I use it myself frequently so I intend to maintain it in the long run.
Opus 96 kb/s (Android) / Vorbis -q5 (PC) / WavPack -hhx6m (Archive)

Re: opusgain scanner implementation status

Reply #11
If anyone is interested, I have written a small command line r128gain scanner/tagger implementation to fill the lack of such tool.
Its written in Python and uses FFmpeg for decoding and R128 loudness analysis.
...
Standalone Windows version now available, which bundles a custom FFmpeg build to analyze all known audio formats.
Opus 96 kb/s (Android) / Vorbis -q5 (PC) / WavPack -hhx6m (Archive)

Re: opusgain scanner implementation status

Reply #12
Do I understand things correctly regarding Opus R128 specifications not allowing for peak information to be saved?

Re: opusgain scanner implementation status

Reply #13
Do I understand things correctly regarding Opus R128 specifications not allowing for peak information to be saved?

Correct.  There is no mechanism in the specification for storing peak data.  In fact the spec explains that they are not needed and not wanted, so there are no R128 peak tags defined.

Re: opusgain scanner implementation status

Reply #14
Do I understand things correctly regarding Opus R128 specifications not allowing for peak information to be saved?

Correct.  There is no mechanism in the specification for storing peak data.  In fact the spec explains that they are not needed and not wanted, so there are no R128 peak tags defined.
Why are they not needed? Maybe it's implicit but I don't get it, sorry. :)

Re: opusgain scanner implementation status

Reply #15
Do I understand things correctly regarding Opus R128 specifications not allowing for peak information to be saved?

Correct.  There is no mechanism in the specification for storing peak data.  In fact the spec explains that they are not needed and not wanted, so there are no R128 peak tags defined.
Why are they not needed? Maybe it's implicit but I don't get it, sorry. :)

Not implicit, quite the opposite.  To quote the standard:
Quote
Peak normalizations are difficult to calculate reliably for lossy codecs because of variation in excursion heights due to decoder differences.  In the authors' investigations, they were not applied consistently or broadly enough to merit inclusion here.