libsndfile / libsndfile

A C library for reading and writing sound files containing sampled audio data.
http://libsndfile.github.io/libsndfile/
GNU Lesser General Public License v2.1
1.42k stars 379 forks source link

SF_BROADCAST_INFO doesn't support BWF Version 2 #479

Closed nachtzug closed 5 years ago

nachtzug commented 5 years ago

Currently SF_BROADCAST_INFO is limted to version 1. Version 2 added 5 R.128 loudness metadata (first 10 Bytes of currently reserved space). Basically, these are just 5 int16_t values (little-endian).

have a look here: https://tech.ebu.ch/docs/tech/tech3285.pdf

Version 2 is a substantial revision of Version 1 which incorporates loudness metadata (in accordance with EBU R 128 [2]) and which takes account of the publication of Supplements 1 – 6 and other relevant documentation. This version is fully compatible with Versions 0 and 1, but users who wish to ensure that their files meet the requirements of EBU Recommendation R 128 will need to ensure that their systems can read and write the loudness metadata.

erikd commented 5 years ago

Patches accepted.

nachtzug commented 5 years ago

you just need to implement read/write-support to these 5 shorts. No extra logic behind. Just extend the struct, reduce "reserved" to 180 bytes and swap bytes on read/write if hostsystem is big endian.

done.

erikd commented 5 years ago

Patches accepted. Hopefully with tests.

Moonbase59 commented 5 years ago

I’d also strongly support including the 5 loudness values mentioned in Tech 3285 (and change the "reserved" to 180 length):

WORD LoudnessValue;        /* WORD : Integrated Loudness Value of the file in LUFS (multiplied by 100) */
WORD LoudnessRange;        /* WORD : Loudness Range of the file in LU (multiplied by 100) */
WORD MaxTruePeakLevel;     /* WORD : Maximum True Peak Level of the file expressed as dBTP (multiplied by 100) */
WORD MaxMomentaryLoudness; /* WORD : Highest value of the Momentary Loudness Level of the file in LUFS (multiplied by 100) */ 
WORD MaxShortTermLoudness; /* WORD : Highest value of the Short-Term Loudness Level of the file in LUFS (multiplied by 100) */
BYTE Reserved[180];        /* 180 bytes, reserved for future use, set to “NULL” */

Rationale: Many programs (like IDJC) use libsndfile, and I plan to support these fields in the bext chunk in my loudgain EBU R128 loudness tagger. The idea behind this is to store EBU R128 loudness info in WAV (BWF) files so that DAWs (Digital Audio Workstations) and IDJC, maybe others, could read and use these.

nachtzug commented 5 years ago

@njh: does that mean, the other (already parsed) values are interpreted as "native-endian"? So I have to take care of it myself (which is not a problem, but this should be consistent and documented). It would be a pain in the ass, if version x.y.0 would not convert it and x.y.1 converts it.

So if there is no conversion yet, it should not be done for the loudness-values also. Otherwise, of course, these values should be converted from little-endian to native-endian.

I ask myself, why version 2 is not already supported. Tech3285 v2 is from 2011. Does that mean, that these bits of code are 8yrs old and never touched since then?

Moonbase59 commented 5 years ago

@erikd Well, I tried to be courageous and prepare a pull request for BWF v2. Please check and let me know what I missed ;-)

njh commented 5 years ago

@nachtzug sorry, I got this completely wrong. There is indeed code to convert the endianness of the integer values of the bext chunk.