FrancisRussell / zoog

Updates Opus headers and R128 tags to normalize playback volume for non-R128-aware players.
BSD 3-Clause "New" or "Revised" License
13 stars 3 forks source link

Perfect tool for my workflow but some features are missing.. #115

Open zuzzurro opened 5 months ago

zuzzurro commented 5 months ago

I have been looking for this tool since I discovered that my opus encoding workflow is subject to the issues you describe in the README and I was ecstatic. I therefore cloned and compiled it to see if I can switch to using opusgain for maintaining the loudness gain of my audio collection and therefore replace "loudness" that is the tool I'm using now, and the result of my test is this issue. Opusgain seems to have what I need AND fix my issue but it also is missing a couple of features:

1) I'm used to be able to pass a recursive (-r) flag to quickly scan and update my whole collection. Would id be possible to add it? 2) Most other tools automatically decide that all opus files in a certain directory are part of the same album. Would this be possible after adding the -r flag? 3) I would sometimes prefer for the tool to avoid changing the modified time of the files it touches. Would that be also possible?

I will of course help out for testing the changes, but unfortunately I'm unable to contribute code (yet) as I'm not familiar with Rust

Thanks

FrancisRussell commented 4 months ago

Hi, just wanted to say I've been looking into/thinking about both the things in this issue.

Regarding modification times, while this is possible, I do have a concern about its affect on backup/file-synchronization. Many tools of this form use the combination of a modification timestamp and the file size to determine if a file has changed. Rewritten media files have a decent chance of remaining the same size, so it's not unlikely that a processed file might be considered to be unchanged by a backup or file synchronization tool, I've been thinking about (and commited to develop, though I might still revert/change) an option that when enabled attempts to increment the modification timestamp by the smallest amount possible (though this is dependent on the underlying filesystem being used so it can be anything from 1 nano-second to 2 seconds for most filesystems in common use). It would be helpful to understand precisely why you'd prefer to keep the modification timestamp unchanged?

Regarding the recursive option, it should be possible to shell-script this behaviour. I believe loudgain includes a separate script to do this for example. I think it can get a bit messy though, in which case I can see the benefit for some basic support inside the tool. I'm not keen on this option assuming or prescribing a particular layout of media files though. vorbisgain's recursive option considers all files in the same folder to be part of the same album, but I can imagine layouts where this behaviour might cause all singles from an artist to be normalized as if they belonged to an album, which isn't ideal.

I am curious what folder layout you have for files, and how it distinguishes between albums and singles. Also, what platform you are on, as this determines the shells available to you for scripting.

zuzzurro commented 4 months ago

Hi. Thanks for your changes and for the long comment. It took me a while for replying because I wanted to experiment a little bit changing the rgbpm script for the implementing the recursive update. I initially thought that the performance would not be great but I got it right opusgain is internally multithreaded and the performance is actually quite good (kudos for that).

In terms of layout my collection uses the standard setup of one folder per CD and while I agree hypothetically there may be problems in some cases, I don't think that happens for my library as most of my collection is full CDs encoded in opus from the FLAC master.

I loved the solution you implemented for the modification times, but when I tried it for real I realized that with this solution the ONLY timestamp that is updated by a single ns is the modification one while the others are updated normally. That result in pretty weird looking times for the files. That may or may not work for I'm trying to achieve, but I need a bit more time for experimenting.

As I said my workflow always start with the original FLACs and the opus files are expendable, I don't quite care about backing them up as I can always recreate them from the originals. What I instead to is setting the opus file times exactly like the ones of the FLAC originals since some player will use the file time for sorting the latest additions to my collection.

I hope this clarifies my needs a bit more..

FrancisRussell commented 3 months ago

I've just merged some changes to make it easier to specify album folders on the command line (--interpret-paths and --file-extensions). While I imagine it will not entirely remove the need for shell scripting, it might reduce the complexity somewhat.

zuzzurro commented 3 months ago

I think the most relevant change for me is the interpret-paths switch with the folders-are-albums value. This is very convenient when used for tagging a single album. It doesn't seem to work very well for the mass-tagging when re-encoding everything from flac. The other tool I am used to is inflexible in the definition of "album" (a leaf folder with audio files in it) but it would work in both the single album and the mass tagging case. Of course in this case a folder is not an "album", it's just a disc. An album with two subfolders (Disc 1 and Disc 2) will not be tagged correctly. The only way it would work is the case of the album created in a single folder with files marked as disc number-track number-track title.. That's also not the format most people use for storing albums, though. Not that I'm complaining, just to give you my 2c worth of perspective..

FrancisRussell commented 3 months ago

It doesn't seem to work very well for the mass-tagging when re-encoding everything from flac.

Could you elaborate on this? I'm unsure if you're referring to the issues you then mention or something else about the behaviour. Maybe an example of errors, or the command line you are running and the folder/file structure that things are not working for?

Given a number of folders and a number of individual files, I assumed this would mostly be able to capture the mass-tagging case, just by using a wildcard path match at the top-level (e.g. opusgain --interpret-paths=folders-are-albums * for a layout structure similar to the one used as an example in the README) . I'm unsure if you used the help text from the executable or the README as well - the README tries to explain the --interpret-paths option in more detail as well as the behaviour used when searching folders.

The other tool I am used to is inflexible in the definition of "album" (a leaf folder with audio files in it) but it would work in both the single album and the mass tagging case. Of course in this case a folder is not an "album", it's just a disc. An album with two subfolders (Disc 1 and Disc 2) will not be tagged correctly.

This is the reason why I made opusgain explore the provided folder recursively for files in the folders-are-albums. In the case that there is a multiple disc album, you probably want the album normalization to apply across all three disks, so this mode it will find all tracks from the sub-folders and normalize them as part of the same album.

zuzzurro commented 3 months ago

OK, I think I see the difference. For me a mass tagging operation would always be performed by just passing the root folder of my music collection, let's say ~/Music/opus. It seems to me that in that case everything will be a single album in the folders-are-albums case. Your suggestion is to pass a * argument for each subfolder that actually contains the albums. Correct?

FrancisRussell commented 3 months ago

Let's assume your music is in ~/music/opus. Let's also assume some files in there:

~/music/opus/single_1.opus
~/music/opus/single_2.opus
~/music/opus/album_1/track_1.opus
~/music/opus/album_1/track_2.opus
~/music/opus/album_1/track_3.opus
~/music/opus/album_2/track_1.opus
~/music/opus/album_2/track_2.opus
~/music/opus/album_2/track_3.opus
~/music/opus/album_3/disc_1/track_1.opus
~/music/opus/album_3/disc_1/track_2.opus
~/music/opus/album_3/disc_2/track_1.opus
~/music/opus/album_3/disc_2/track_2.opus
~/music/opus/album_3/track_3.opus

The to normalize this, you would go to ~/music/opus/ then run opusgain -i folders-are-albums *. This would get expanded by the shell to opusgain -i folders-are-albums single_1.opus single_2.opus album_1 album_2 album_3 (you can see the expansion by just preceeding the command with echo, e.g. echo opusgain -i folders-are-albums *).

The result should be that single_1.opus and single_2.opus are normalized as singles. album_1 and album_2 are normalized as albums as expected. All tracks from album_3 are normalized together as if they are a single album, despite the disc_1 and disc_2 sub-folders.

zuzzurro commented 3 months ago

Yeah, that was clear to me now, thanks. My issue is that my folder structure depth is not constant. Sometimes I have subfolders like HighRes that contain high-res albums, for instance. What's constant is the view from the leaves. A leaf folder normally contains a disc and sometime the disc is part of an album (one level up).

zuzzurro commented 3 months ago

Anyway, nothing to worry about, the quirky nature of my folder structure is a problem known to me and I also know how I could fix it (by using tools like beets and renaming/restructring all my collection) but that is a daunting task per se and that I also balk at making for other reasons. One last thing. One of the reasons why I originally did not really read well/consider your README about using "*" is that I normally dislike using globbing on very large folders because the globbing may fail due to lack of space (NCARGS). I was thinking whether passing the list of files/folder thru a file (à la rsync "--files-from") would be possible. But please, consider that what's already there is totally fine for me. I switched to using opusgain a month ago and for the time being I'm just tagging on a per album basis and this already works absolutely fine. Thanks a lot again for your support.