shithub: opus-tools

Download patch

ref: ef87ba9330fd59b1ef56b5811be63c49b3536450
parent: 1987a0a4b85d87768a2699e0a3d7d930857e78c2
author: Mark Harris <mark.hsj@gmail.com>
date: Sat Jun 19 17:47:15 EDT 2021

opusenc: Handle LUFS reference loudness in FLAC

Handle the FLAC comment REPLAYGAIN_REFERENCE_LOUDNESS expressed in
either dB SPL (positive) or LUFS (negative).  Although the FLAC
reference software writes dB SPL, some other software (such as
loudgain -s e) writes LUFS.

Fixes https://gitlab.xiph.org/xiph/opus-tools/-/issues/2316

--- a/src/flac.c
+++ b/src/flac.c
@@ -122,8 +122,9 @@
         comments=metadata->data.vorbis_comment.comments;
         saw_album_gain=saw_track_gain=0;
         album_gain=track_gain=0;
-        /*The default reference loudness for ReplayGain is 89.0 dB*/
-        reference_loudness=89;
+        /*The default reference loudness for ReplayGain is 89 dB SPL,
+          or -18 LUFS measured according to ITU-R BS.1770 / EBU R128.*/
+        reference_loudness=-18;
         /*The code below uses strtod for the gain tags, so make sure the locale is C*/
         saved_locale=setlocale(LC_NUMERIC,"C");
         for(i=0;i<num_comments;i++){
@@ -134,11 +135,15 @@
           /*Check for ReplayGain tags.
             Parse the ones we have R128 equivalents for, and skip the others.*/
           if(tagcompare(entry,"REPLAYGAIN_REFERENCE_LOUDNESS=",30)==0){
+            /*Reference loundness may be in dB SPL (positive) or
+              LUFS (negative).  The 89 dB SPL reference is considered
+              to be the same loudness as -18 LUFS.*/
             gain=strtod(entry+30,&end);
             if(end<=entry+30){
               fprintf(stderr,_("WARNING: Invalid ReplayGain tag: %s\n"),entry);
             }
-            else reference_loudness=gain;
+            else if (gain<0) reference_loudness=gain;
+            else reference_loudness=gain-89-18;
             continue;
           }
           if(tagcompare(entry,"REPLAYGAIN_ALBUM_GAIN=",22)==0){
@@ -177,9 +182,9 @@
         }
         setlocale(LC_NUMERIC,saved_locale);
         /*Set the header gain to the album gain after converting to the R128
-          reference level.*/
+          reference level (-23 LUFS).*/
         if(saw_album_gain){
-          gain=256*(album_gain+(84-reference_loudness))+0.5;
+          gain=256*(album_gain+(-23-reference_loudness))+0.5;
           inopt->gain=gain<-32768?-32768:gain<32767?(int)floor(gain):32767;
         }
         /*If there was a track gain, then add an equivalent R128 tag for that.*/