also, (again, newbie question) can I pass the full -sox comand line to the program (through windows .bat file or shortcut)? I tried --command=sox "%TRACK%" "%DN%\%BN%.wav" gain "%TGDB%" but all thouse quotes seem to confuse the .bat fileYou should surround it by quotes, i.e. either

'--command=sox "%TRACK%" "%DN%\%BN%.wav" gain "%TGDB%"'

or

"--command=sox '%TRACK%' '%DN%\%BN%.wav' gain '%TGDB%'"

Thanks mate, I'm going to sound like an idiot, but I tried a few variations of quotes swapping in my .bat file but I couldn't get it to pass the variables to the sox command.

It creates the convertedto-24 directory and then fails before writing.I'm sure I am being thick but what did I do wrong?I can get the command to work in the win32 gui (without the preamp option) but not with the bat file.

Hello to this active community,and millions of thanks to Mr. Belkner for his efforts with this project, most appreciated.

I understand r128gain is using RG parameters as the Output, and I was wondering if it would be possible to use BWF (Broadcast Wave Format) Tags alternatively. I know there is a BWF "Loudness" Chunk standardisation underway currently, and all the broadcasters are using BWF anyway (and not mp3 or FLAC). We use BWF (and RF64 for multichannel files >2GB) for all our mpeg1LayerII and linear files, and this tool could be a tremendous help for many applications across a broadcast workflow (analysis/corrected on playout/corrected in the file directly)

Added an option to the command line (--tags=[rg|bwf]) and the GUI (drop down box) for letting R128GAIN write BWF tags instead of ReplayGain tags. The following BWF tags are currently supported (depending on the format they may appear converted to upper case):

LoudnessValue

LoudnessRange

MaxTruePeakLevel

QUOTE (audioworld @ Apr 1 2012, 20:23)

We use BWF (and RF64 for multichannel files >2GB) for all our mpeg1LayerII and linear files, and this tool could be a tremendous help for many applications across a broadcast workflow (analysis/corrected on playout/corrected in the file directly)

Please note that whether the BWF format itself is supported or not depends on whether FFmpeg or SoX, respectively, is supporting it.

I do not want to think about how long it would have taken a commercial software company to implement BWF loudness Tags, and you are able to pull this off within 24 hours as a "side project"!!! Congratulations and thank you so much!

As the chairman from the EBU R128 working group is a good friend and colleague of mine, I will communicate your efforts to this EBU group and additionally to all the public broadcasters in germany which are currently searching for tools to implement R128. I know that you are doing this in your free time and really hope there are some broadcasters placing commercial orders for further adaptions and integrations with you, to give you some kind of compensation for everything you are doing for the R128 loudness standard.

Thanks and respect, karl.

PS: a small observation in the dropdown-box for the output metadata format: It should read "BWF" and not "BFW"

I do not want to think about how long it would have taken a commercial software company to implement BWF loudness Tags, and you are able to pull this off within 24 hours as a "side project"!!! Congratulations and thank you so much!

As the chairman from the EBU R128 working group is a good friend and colleague of mine, I will communicate your efforts to this EBU group and additionally to all the public broadcasters in germany which are currently searching for tools to implement R128. I know that you are doing this in your free time and really hope there are some broadcasters placing commercial orders for further adaptions and integrations with you, to give you some kind of compensation for everything you are doing for the R128 loudness standard.

I'm interested in trying R128 volume for my lossless collection (ripped CDs, stereo @ 44100 Hz). However, I want to discover the reported "gain" and "range" values for each track, not a copy of the file with some tags applied. So I need some help here. This post is mostly directed to pbelkner and since it was written in a hurry, it's dense and probably incomprehensible; I'll gladly explain everything if asked to.

LIBRARY BUILDING RELATEDI work on an Ubuntu 11.10 64-bit environment. I downloaded lib1770-0.6-src.tar.gz . Trying to compile it (the source has a little bit unusual structure for me), I got errors on linking because the source files were not compiled with PIC (position independent code). I edited src/lib1770/common.mk and right below `CFLAGS+=-mfpmath=sse` I added a line `CFLAGS+=-fPIC`. `make clean; make` produced a static and a dynamic version of the library. `make install` was unhelpful (copied to some directories relative to my current directory), so I copied the .so and the .h files to the relevant /usr/local/@(lib|include) directories.

USING THE LIBRARYNow, I would like to verify/have documentation for the correct calls to the following functions:

2. for every (left, right) sample of a track, bs1770_ctx_add_sample gets called with: ctx (the context created), double fs (=44100.0?), int channels (=2), bs1770_sample_t sample (basically, an array of max 5 doubles; typically I will fill the first two doubles since channels == 2; however, do I have to divide the short int sample by 32768.0 so my sample values become [-1.0,1.0) ? )

THE GIST OF ITSo, given that I easily can get the raw samples (stereo, 44100 Hz, 16-bit samples) from my collection, what are the steps to take to calculate R128-compatible (including the gating of silence or near-silence) suggested track gain and loudness range?

NOTEI have a mechanism already in place that prepares audio for car-listening; based on the pre-calculated RG gain values, a crude way to calculate loudness range (basically, the standard deviation of RMS values of the audio sectors/frames (1/75 sec) ) and some manually-inserted adjustments (as tags), I create .ogg files (with per-track varying dynamic compression applied) for my car-listening pleasure. RG over-attenuates tracks with too much dynamic compression, and over-amplifies mostly silent tracks. Reading about R128, I got my hopes up that my manual intervention can be reduced.

I'm interested in trying R128 volume for my lossless collection (ripped CDs, stereo @ 44100 Hz). However, I want to discover the reported "gain" and "range" values for each track, not a copy of the file with some tags applied. So I need some help here. This post is mostly directed to pbelkner and since it was written in a hurry, it's dense and probably incomprehensible; I'll gladly explain everything if asked to.

...

The build process is not compliant with "autotools" because I'm struggling on several fronts and simply didn't found the time so far to look at "autotools".

Currently I'm rewriting the whole program. The main goals for the rewrite are to provide UNICODE support for Windows, a GTK GUI for Linux, remove each static buffers from the program and base everything on consolidated grounds. The current state of the rewrite is that the programm itself is stable but the build process is not in a fashion I'd like to have it.

The new build process should follow the "./configure; make && make install" pattern, at least in a restricted way. The restriction mainly is that the "configure" scripts will be "home grown", i.e. not generated by "autotools". These "configure" scripts will allow for providing "CFLAGS", "LDFLGS" and "LIBS" and will allow for "out of tree" builds. Having this done will take some more weeks.

I should add as a goal for the new version to provide 64 bit builds (implying that the build process is tested on 64 bit.)

If you are able to build the current version at 64 bit, there should be no problem to run just an analysis by omitting the "-o" option. The result of the analysis is written to "stdout" and can be parsed from there using e.g. "sed".

If you like to embed "lib1770" into a program you should have a look at "example1.c" provided with the source of "lib1770".

If you like to embed "lib1770" into a program you should have a look at "example1.c" provided with the source of "lib1770".

Thank you. I did that and had success (I changed RATE to 44100, made buf into static short array multiplying each sample by 1.0/32768.0). However, I obviously get only the suggested gain, not the loudness range. I perused the source of r128gain and found the commented-out BWF_AR defines, but no other mentions. Can I assume that the loudness range functionality is not yet implemented? I'm not pressuring; I'm asking to stop looking for it if it isn't there.Again, thank you very much for both spending time to develop r128gain/lib1770 and answering here to all of us.

If you like to embed "lib1770" into a program you should have a look at "example1.c" provided with the source of "lib1770".

Thank you. I did that and had success (I changed RATE to 44100, made buf into static short array multiplying each sample by 1.0/32768.0). However, I obviously get only the suggested gain, not the loudness range. I perused the source of r128gain and found the commented-out BWF_AR defines, but no other mentions. Can I assume that the loudness range functionality is not yet implemented? I'm not pressuring; I'm asking to stop looking for it if it isn't there.Again, thank you very much for both spending time to develop r128gain/lib1770 and answering here to all of us.

If you look at "exampel1.c" you'll find a symbol "LRU" defined:

If the symbol is defined, the example program calculates the loudness range in LU.

If the symbol is undefined, the example program calculates the (absolute) loudness in LUFS (not a gain).

If the symbol is defined, the example program calculates the loudness range in LU.

If the symbol is undefined, the example program calculates the (absolute) loudness in LUFS (not a gain).

That's great. So, for my very specific case, I create two contexts, one for the loudness range and one for the absolute loudness (each with the suggested values for gate, block and partition) and at the end I report both. Thank you.

First of all, thanks for doing this, and suport, I use r128gain mainly as a command line utility - and it's a great help. I use normalize to adjust volumes and r128gain to monitor the outcome and necessary adjustment.

I don't want you to misinterpret the few notes and opinions that I wrote below, I think the program is great and it's a fantastic effort, and I'm not bashing, just trying to highlight few larger problems.

I think we are jumping slightly too far ahead with new releases focusing on GUI for linux, because as is, the GUI bit would be relatively niche requirement, and meanwhile none of releases actually compile correctly under linux even as a command line utility, so introducing additional elements will just create bigger mess. As it is, r128gain fails to compile "out of the box" on just about every distro I've tried - I usually try each release on centos, gentoo and debian.

All previous versions were nearly impossible to compile on most 64 bit linux distros which most of us use these days, because source is not using -fPIC anywhere in the code. I used to bypass this by manually fixing every Makefile and common.mk and adding it to CFLAGS where ever possible, but the new version doesn't seem to use common flags anymore so even after changing CFLAGS in Makefile it still fails while linking files in lib1770. I don't know enough about compiling to fix it this time.

In new alpha 'make' won't even start if the GUI:= value is ommited in config.mak, so those of us who use server linux distros without full desktops, can't even use it.

Compilation of r128 on 32bit linuxes was usually slightly easier in general but there is still a lot to fix, bits failing all over the place with several config files failing to execute because they don't have +x permissions. The undocumented manual download of ffmpeg-export-snapshot.tar.lzma inside another randomly named tar with full paths stored plus the fact that many linuxes in "stable" tree don't have the latest tar with lzma, so extractions fail with "tar: unrecognized option `--lzma'" (as example Fedora has it, because it's "cutting edge", Centos and Redhat don't have it, because "stable" branch use old 1.5x. And so on, so forth.

Realistically, static build would probably be the best answer, but I understand it might not be possible with current resources and time you have for this development.

When I pass a file path with spaces and without "enclosing quotes", or a file which doesn't exist, it prints an assert and crashes.

Other than that, it seems to analyze as expected, but I have some questions after looking at the source code.

For the loudness analysis, all input files are resampled to 48 kHz, right? For the peak finder, the files are additionally resampled to 192 kHz, right? The way I understand R128 is: Pass 1: analyze entire file/album, compute loudness taking into account the absolute gate of -70 LUFS. Pass 2: analyze entire file/album again, this time also taking into account the relative loudness gate derived from the result of pass 1. Is that how you implemented it?

For the peak finder, the files are additionally resampled to 192 kHz, right?

This is true only for "true peak" mode, which is the default (cf. "r128gain_s_r128.c".) You may choose "peak off" mode or "sample peak" mode instead.

QUOTE (longnvl @ May 25 2012, 08:06)

For the loudness analysis, all input files are resampled to 48 kHz, right?

That's wrong. If they where up-sampled because of "true peak" mode, they will be down-sampled to the original rate before the loudness analysis, in "peak off" and "sample peak" modes the original sample rate is used anyway (cf. "r128gain_s_r128.c".)

QUOTE (longnvl @ May 25 2012, 08:06)

The way I understand R128 is:Pass 1: analyze entire file/album, compute loudness taking into account the absolute gate of -70 LUFS.Pass 2: analyze entire file/album again, this time also taking into account the relative loudness gate derived from the result of pass 1. Is that how you implemented it?

No. There's only one pass using a histogram (cf. "bs1170_stats_h.c", the slow two-pass implementation "bs1170_stats_s.c" is maintained only for historical reasons.) The gate of -70 LUFS is set in "bs1170_stats.c".

The reason is that the new UNICODE enabled version uses __wgetmainargs() to convert the command line from OEM to UNICODE. Unfortunately __wgetmainargs() seems not to be available on systems with older Windows versions, as it is on my Vista.