commit:     063b3d6de78ce7417e2df7e4c7433a29b89dc5cd
Author:     YOSHIOKA Takuma <lo48576 <AT> hard-wi <DOT> red>
AuthorDate: Tue Nov 18 23:56:03 2025 +0000
Commit:     YOSHIOKA Takuma <lo48576 <AT> hard-wi <DOT> red>
CommitDate: Wed Nov 19 00:06:39 2025 +0000
URL:        https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=063b3d6d

media-sound/loudgain: add 0.6.8_p20240128-r3

Use v0.6.8 release archive and apply manually extracted patches instead
of downloading a commit archive from GitHub. This makes it possible to
share the source archive between 0.6.8-rN and 0.6.8_p20240128-rN.
I'm a not big fan of having lots of patches in files/ directory instead
of using an upstream commit archive, but loudgain repository (and a
commit archives as well) have prebuilt binary inside it, so it would be
beneficial to use fixed version of release archive. I feel that the
amount of patches are still acceptable.

Bump minimum required CMake version. See bug #951350.

Add a new rgbpm2 script, which is multi-processing version of rgbpm.
This was added to the upstream master branch after 0.6.8, but not yet
released.

I believe this ebuild can replace loudgain-0.6.8_p20240128-r2.ebuild
(and also loudgain-0.6.8-r2.ebuild), but considering the amount of
ebuild changes, I will keep those old ebuilds for a while.

Signed-off-by: YOSHIOKA Takuma <lo48576 <AT> hard-wi.red>

 .../loudgain/files/loudgain-0.6.8-cmake-4.patch    |  15 ++
 ...oudgain-0.6.8-github-20190906-manpage-ape.patch |  62 ++++++
 ...oudgain-0.6.8-github-20190918-taglib-1.12.patch | 239 +++++++++++++++++++++
 .../loudgain-0.6.8-github-20190930-rgbpm2.patch    | 234 ++++++++++++++++++++
 .../loudgain/loudgain-0.6.8_p20240128-r3.ebuild    |  47 ++++
 5 files changed, 597 insertions(+)

diff --git a/media-sound/loudgain/files/loudgain-0.6.8-cmake-4.patch 
b/media-sound/loudgain/files/loudgain-0.6.8-cmake-4.patch
new file mode 100644
index 0000000000..0d67a8eeef
--- /dev/null
+++ b/media-sound/loudgain/files/loudgain-0.6.8-cmake-4.patch
@@ -0,0 +1,15 @@
+Picked 3.31 just because it is the oldest dev-build/cmake in ::gentoo as of 
2025-11-19.
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 9487ab98a594..a9219cd2cf39 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -3,7 +3,7 @@
+ # Modifications Copyright (C) 2019 Matthias C. Hormann <[email protected]>
+ # This file is released under the 2 clause BSD license, see COPYING
+ 
+-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
++CMAKE_MINIMUM_REQUIRED(VERSION 3.31)
+ PROJECT(loudgain C CXX)
+ 
+ SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})

diff --git 
a/media-sound/loudgain/files/loudgain-0.6.8-github-20190906-manpage-ape.patch 
b/media-sound/loudgain/files/loudgain-0.6.8-github-20190906-manpage-ape.patch
new file mode 100644
index 0000000000..15e051b3b1
--- /dev/null
+++ 
b/media-sound/loudgain/files/loudgain-0.6.8-github-20190906-manpage-ape.patch
@@ -0,0 +1,62 @@
+https://github.com/Moonbase59/loudgain/compare/508b6fd63cfc8b3db67a0eb19d87a036543325f4...d6ae9c08ca0e88cc3caebd499185c26f9c1420da
+(but stripped docs/loudgain.1.html diff since they won't be installed to the 
system.)
+From 31f46fcc55b56618730e269640d671ce65891612 Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Fri, 6 Sep 2019 18:18:33 +0200
+Subject: [PATCH 1/2] README: Add APE to introduction
+
+---
+ README.md | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/README.md b/README.md
+index e77fb72..1f82fa2 100644
+--- a/README.md
++++ b/README.md
+@@ -1,6 +1,6 @@
+ # loudgain
+ 
+-**loudgain** is a versatile ReplayGain 2.0 loudness normalizer, based on the 
EBU R128/ITU BS.1770 standard (-18 LUFS) and supports 
FLAC/Ogg/MP2/MP3/MP4/M4A/ALAC/Opus/ASF/WMA/WAV/WavPack/AIFF audio files. It 
uses the well-known `mp3gain` commandline syntax but will never modify the 
actual audio data.
++**loudgain** is a versatile ReplayGain 2.0 loudness normalizer, based on the 
EBU R128/ITU BS.1770 standard (-18 LUFS) and supports 
FLAC/Ogg/MP2/MP3/MP4/M4A/ALAC/Opus/ASF/WMA/WAV/WavPack/AIFF/APE audio files. It 
uses the well-known `mp3gain` commandline syntax but will never modify the 
actual audio data.
+ 
+ Just what you ever wanted: The best of mp3gain, ReplayGain 2.0 and Linux 
combined. **Spread the word!**
+ 
+
+From d6ae9c08ca0e88cc3caebd499185c26f9c1420da Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Sat, 7 Sep 2019 11:01:09 +0200
+Subject: [PATCH 2/2] man page: Add APE to 's- i'
+
+---
+ docs/loudgain.1      |  2 +-
+ docs/loudgain.1.html | 10 +++++-----
+ docs/loudgain.1.md   |  2 +-
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/docs/loudgain.1 b/docs/loudgain.1
+index 8f59138..93124b9 100644
+--- a/docs/loudgain.1
++++ b/docs/loudgain.1
+@@ -67,7 +67,7 @@ Delete ReplayGain tags from files\.
+ .
+ .TP
+ \fB\-s i, \-\-tagmode=i\fR
+-Write ReplayGain 2\.0 tags to files\. ID3v2 for MP2, MP3, WAV and AIFF; 
Vorbis Comments for FLAC, Ogg, Speex and Opus; iTunes\-type metadata for 
MP4/M4A; WMA tags for ASF/WMA; APEv2 tags for WavPack\.
++Write ReplayGain 2\.0 tags to files\. ID3v2 for MP2, MP3, WAV and AIFF; 
Vorbis Comments for FLAC, Ogg, Speex and Opus; iTunes\-type metadata for 
MP4/M4A; WMA tags for ASF/WMA; APEv2 tags for WavPack and APE\.
+ .
+ .TP
+ \fB\-s e, \-\-tagmode=e\fR
+diff --git a/docs/loudgain.1.md b/docs/loudgain.1.md
+index 7a2ed0a..42082e5 100644
+--- a/docs/loudgain.1.md
++++ b/docs/loudgain.1.md
+@@ -57,7 +57,7 @@ Experimental, use with care: WAV (.wav), AIFF (.aiff, .aif, 
.snd).
+ * `-s i, --tagmode=i`:
+   Write ReplayGain 2.0 tags to files. ID3v2 for MP2, MP3, WAV and AIFF; Vorbis
+   Comments for FLAC, Ogg, Speex and Opus; iTunes-type metadata for MP4/M4A;
+-  WMA tags for ASF/WMA; APEv2 tags for WavPack.
++  WMA tags for ASF/WMA; APEv2 tags for WavPack and APE.
+ 
+ * `-s e, --tagmode=e`:
+   like '-s i', plus extra tags (reference, ranges).
+

diff --git 
a/media-sound/loudgain/files/loudgain-0.6.8-github-20190918-taglib-1.12.patch 
b/media-sound/loudgain/files/loudgain-0.6.8-github-20190918-taglib-1.12.patch
new file mode 100644
index 0000000000..c87b965b23
--- /dev/null
+++ 
b/media-sound/loudgain/files/loudgain-0.6.8-github-20190918-taglib-1.12.patch
@@ -0,0 +1,239 @@
+https://github.com/Moonbase59/loudgain/compare/d6ae9c08ca0e88cc3caebd499185c26f9c1420da...afc54b388232b88935ee725b1a0b677773c128e5
+(but stripped docs/loudgain.1.html diff since they won't be installed to the 
system.)
+From 0e03353e6d90198204c2edd9ccf9ecaad6a8e7c8 Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Wed, 18 Sep 2019 16:19:22 +0200
+Subject: [PATCH 1/3] Prepare for TagLib 1.12
+
+---
+ src/tag.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 45 insertions(+), 8 deletions(-)
+
+diff --git a/src/tag.cc b/src/tag.cc
+index c8d3528..16a3716 100644
+--- a/src/tag.cc
++++ b/src/tag.cc
+@@ -56,6 +56,10 @@
+ 
+ #include <taglib.h>
+ 
++#define TAGLIB_VERSION (TAGLIB_MAJOR_VERSION * 10000 \
++                        + TAGLIB_MINOR_VERSION * 100 \
++                        + TAGLIB_PATCH_VERSION)
++
+ #include <textidentificationframe.h>
+ 
+ #include <mpegfile.h>
+@@ -204,7 +208,13 @@ bool tag_write_mp3(scan_result *scan, bool do_album, char 
mode, char *unit,
+   if (strip)
+     f.strip(TagLib::MPEG::File::APE);
+ 
++#if TAGLIB_VERSION >= 11200
++  return f.save(TagLib::MPEG::File::ID3v2,
++    strip ? TagLib::MPEG::File::StripOthers : TagLib::MPEG::File::StripNone,
++    id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save(TagLib::MPEG::File::ID3v2, strip, id3v2version);
++#endif
+ }
+ 
+ bool tag_clear_mp3(scan_result *scan, bool strip, int id3v2version) {
+@@ -217,7 +227,13 @@ bool tag_clear_mp3(scan_result *scan, bool strip, int 
id3v2version) {
+   if (strip)
+     f.strip(TagLib::MPEG::File::APE);
+ 
++#if TAGLIB_VERSION >= 11200
++  return f.save(TagLib::MPEG::File::ID3v2,
++    strip ? TagLib::MPEG::File::StripOthers : TagLib::MPEG::File::StripNone,
++    id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save(TagLib::MPEG::File::ID3v2, strip, id3v2version);
++#endif
+ }
+ 
+ 
+@@ -490,10 +506,17 @@ TagLib::String tagname(TagLib::String key) {
+ 
+ void tag_remove_mp4(TagLib::MP4::Tag *tag) {
+   TagLib::String desc;
+-  TagLib::MP4::ItemListMap &items = tag->itemListMap();
++#if TAGLIB_VERSION >= 11200
++  TagLib::MP4::ItemMap items = tag->itemMap();
+ 
+-  for(TagLib::MP4::ItemListMap::Iterator item = items.begin();
++  for(TagLib::MP4::ItemMap::Iterator item = items.begin();
+       item != items.end(); ++item)
++#else
++TagLib::MP4::ItemListMap &items = tag->itemListMap();
++
++for(TagLib::MP4::ItemListMap::Iterator item = items.begin();
++    item != items.end(); ++item)
++#endif
+   {
+     desc = item->first.upper();
+     if ((desc == tagname(RG_STRING_UPPER[RG_TRACK_GAIN]).upper()) ||
+@@ -715,7 +738,13 @@ bool tag_write_wav(scan_result *scan, bool do_album, char 
mode, char *unit,
+   }
+ 
+   // no stripping
++#if TAGLIB_VERSION >= 11200
++  return f.save(TagLib::RIFF::WAV::File::AllTags,
++    TagLib::RIFF::WAV::File::StripNone,
++    id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save(TagLib::RIFF::WAV::File::AllTags, false, id3v2version);
++#endif
+ }
+ 
+ bool tag_clear_wav(scan_result *scan, bool strip, int id3v2version) {
+@@ -725,7 +754,13 @@ bool tag_clear_wav(scan_result *scan, bool strip, int 
id3v2version) {
+   tag_remove_wav(tag);
+ 
+   // no stripping
++#if TAGLIB_VERSION >= 11200
++  return f.save(TagLib::RIFF::WAV::File::AllTags,
++    TagLib::RIFF::WAV::File::StripNone,
++    id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save(TagLib::RIFF::WAV::File::AllTags, false, id3v2version);
++#endif
+ }
+ 
+ 
+@@ -804,10 +839,11 @@ bool tag_write_aiff(scan_result *scan, bool do_album, 
char mode, char *unit,
+   }
+ 
+   // no stripping
+-  // unfortunately, TagLib::RIFF::AIFF::File::save() doesn’t provide
+-  // the "Tags, strip, id3v2version" parameters,
+-  // so all files will get the default ID3v2.4 tags. :-(
++#if TAGLIB_VERSION >= 11200
++  return f.save(id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save();
++#endif
+ }
+ 
+ bool tag_clear_aiff(scan_result *scan, bool strip, int id3v2version) {
+@@ -817,10 +853,11 @@ bool tag_clear_aiff(scan_result *scan, bool strip, int 
id3v2version) {
+   tag_remove_aiff(tag);
+ 
+   // no stripping
+-  // unfortunately, TagLib::RIFF::AIFF::File::save() doesn’t provide
+-  // the "Tags, strip, id3v2version" parameters,
+-  // so all files will get the default ID3v2.4 tags.
++#if TAGLIB_VERSION >= 11200
++  return f.save(id3v2version == 3 ? TagLib::ID3v2::v3 : TagLib::ID3v2::v4);
++#else
+   return f.save();
++#endif
+ }
+ 
+ 
+
+From efd0aae91c5c72c85dc63d67613c066a45cc7fdb Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Wed, 18 Sep 2019 18:25:02 +0200
+Subject: [PATCH 2/3] README.md: Explain AIFF ID3v2 options (taglib 1.12)
+
+---
+ README.md | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/README.md b/README.md
+index 1f82fa2..3d0d05c 100644
+--- a/README.md
++++ b/README.md
+@@ -912,14 +912,15 @@ so we can finalize loudgain's Opus support. Thanks!
+    into the "ID3 " chunk. This is a format compatible with _foobar2000_, 
_Mp3tag_,
+    _VLC_ and some others.
+ 
+-   **Note:** Due to a deficiency in _TagLib_, only _ID3v2.4_ tags can 
currently
+-   be written, albeit iTunes and dBPowerAmp can only handle ID3v2.2 or 
ID3v2.3.
+-   Please vote for [TagLib issue 
#922](https://github.com/taglib/taglib/issues/922).
++   **Note:** _TagLib_ versions before _1.12_ could only write _ID3v2.4_ tags, 
albeit
++   iTunes and dBPowerAmp may only handle ID3v2.2 or ID3v2.3 correctly.
++   Starting with _TagLib 1.12_, loudgain supports selecting between _ID3v2.3_ 
and
++   _ID3v2.4_ (default). Use the `-I 3` (`--id3v2version=3`) and `-I 4` 
(`--id3v2version=4`)
++   commandline options for that.
+ 
+ 2. Since ID3v2 tags are written, the `-L` (`--lowercase`) option functions 
normally.
+ 
+-3. The `-S` (`--striptags`), `-I 3` (`--id3v2version=3`) and `-I 4` 
(`--id3v2version=4`)
+-   options are ignored, even when specified.
++3. The `-S` (`--striptags`) option will be ignored, even when specified.
+ 
+ 4. **[Uppercase vs. lowercase 
tags](#uppercase-or-lowercase-replaygain_-tags)**
+    is still a problem:
+
+From afc54b388232b88935ee725b1a0b677773c128e5 Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Wed, 18 Sep 2019 18:48:51 +0200
+Subject: [PATCH 3/3] Update help, man page for upcoming TagLib 1.12
+
+---
+ docs/loudgain.1      |  4 ++--
+ docs/loudgain.1.html | 12 ++++++------
+ docs/loudgain.1.md   |  4 ++--
+ src/loudgain.c       |  6 +++---
+ 4 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/docs/loudgain.1 b/docs/loudgain.1
+index 93124b9..0aaeac2 100644
+--- a/docs/loudgain.1
++++ b/docs/loudgain.1
+@@ -91,11 +91,11 @@ Strip tag types other than ID3v2 from MP2/MP3 files 
(i\.e\. ID3v1, APEv2)\. Stri
+ .
+ .TP
+ \fB\-I 3, \-\-id3v2version=3\fR
+-Write ID3v2\.3 tags to MP2/MP3/WAV files\.
++Write ID3v2\.3 tags to MP2/MP3/WAV/AIFF files\.
+ .
+ .TP
+ \fB\-I 4, \-\-id3v2version=4\fR
+-Write ID3v2\.4 tags to MP2/MP3/WAV files (default)\.
++Write ID3v2\.4 tags to MP2/MP3/WAV/AIFF files (default)\.
+ .
+ .TP
+ \fB\-o, \-\-output\fR
+diff --git a/docs/loudgain.1.md b/docs/loudgain.1.md
+index 42082e5..5624d7f 100644
+--- a/docs/loudgain.1.md
++++ b/docs/loudgain.1.md
+@@ -77,10 +77,10 @@ Experimental, use with care: WAV (.wav), AIFF (.aiff, 
.aif, .snd).
+   Strip tag types other than APEv2 from WavPack/APE files (i.e. ID3v1).
+ 
+ * `-I 3, --id3v2version=3`:
+-  Write ID3v2.3 tags to MP2/MP3/WAV files.
++  Write ID3v2.3 tags to MP2/MP3/WAV/AIFF files.
+ 
+ * `-I 4, --id3v2version=4`:
+-  Write ID3v2.4 tags to MP2/MP3/WAV files (default).
++  Write ID3v2.4 tags to MP2/MP3/WAV/AIFF files (default).
+ 
+ * `-o, --output`:
+   Database-friendly tab-delimited list output (mp3gain-compatible).
+diff --git a/src/loudgain.c b/src/loudgain.c
+index 8d752af..04f40e3 100644
+--- a/src/loudgain.c
++++ b/src/loudgain.c
+@@ -667,7 +667,7 @@ static inline void help(void) {
+       printf("%s %s supports writing tags to the following file types:\n", 
PROJECT_NAME, PROJECT_VER);
+       puts("  FLAC (.flac), Ogg (.ogg, .oga, .spx, .opus), MP2 (.mp2), MP3 
(.mp3),");
+       puts("  MP4 (.mp4, .m4a), ASF/WMA (.asf, .wma), WavPack (.wv), APE 
(.ape).");
+-      puts("  Experimental: WAV (.wav), AIFF (.aiff, .aif).\n");
++      puts("  Experimental: WAV (.wav), AIFF (.aiff, .aif, .snd).\n");
+ 
+       if (warn_ebu) {
+               printf("%sWarning:%s Your EBU R128 library (libebur128) is 
version %s.\n", COLOR_RED, COLOR_OFF, ebur128_version);
+@@ -707,8 +707,8 @@ static inline void help(void) {
+       CMD_CONT("This is non-standard but sometimes needed");
+       CMD_HELP("--striptags", "-S", "Strip tag types other than ID3v2 from 
MP2/MP3");
+       CMD_CONT("Strip tag types other than APEv2 from WavPack/APE");
+-      CMD_HELP("--id3v2version=3", "-I 3", "Write ID3v2.3 tags to MP2/MP3/WAV 
files");
+-      CMD_HELP("--id3v2version=4", "-I 4", "Write ID3v2.4 tags to MP2/MP3/WAV 
files (default)");
++      CMD_HELP("--id3v2version=3", "-I 3", "Write ID3v2.3 tags to 
MP2/MP3/WAV/AIFF");
++      CMD_HELP("--id3v2version=4", "-I 4", "Write ID3v2.4 tags to 
MP2/MP3/WAV/AIFF (default)");
+ 
+       puts("");
+ 

diff --git 
a/media-sound/loudgain/files/loudgain-0.6.8-github-20190930-rgbpm2.patch 
b/media-sound/loudgain/files/loudgain-0.6.8-github-20190930-rgbpm2.patch
new file mode 100644
index 0000000000..eea4f358ee
--- /dev/null
+++ b/media-sound/loudgain/files/loudgain-0.6.8-github-20190930-rgbpm2.patch
@@ -0,0 +1,234 @@
+https://github.com/Moonbase59/loudgain/commit/b59e3c520af0b36d09693c70a44ed4d3585f5b8a
+From b59e3c520af0b36d09693c70a44ed4d3585f5b8a Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Wed, 30 Oct 2019 05:12:30 +0100
+Subject: [PATCH] Add multiprocessing rgbpm2 script for mass-tagging
+
+---
+ bin/rgbpm2 | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 178 insertions(+)
+ create mode 100755 bin/rgbpm2
+
+diff --git a/bin/rgbpm2 b/bin/rgbpm2
+new file mode 100755
+index 0000000..0080a9a
+--- /dev/null
++++ b/bin/rgbpm2
+@@ -0,0 +1,178 @@
++#!/usr/bin/env python
++# -*- coding: utf-8 -*-
++
++# Copyright (c) 2019 Matthias C. Hormann
++
++from __future__ import print_function
++
++import os
++import errno
++import sys
++import signal
++import argparse
++import textwrap
++import fnmatch
++import subprocess
++import multiprocessing
++
++def init_worker():
++    """Initialize workers so they can’t get a KeyboardInterrupt
++    """
++    signal.signal(signal.SIGINT, signal.SIG_IGN)
++
++def loudgain(args):
++    """loudgain args
++    args[0] = folder
++    args[1] = file extension
++    args[2:n] = loudgain options
++    args[n+1:] = filenames
++    """
++    print("Working on {} ...".format(os.path.abspath(os.path.join(args[0],
++        '*' + args[1]))))
++    try:
++        retcode = subprocess.check_call(['loudgain', '-q'] + args[2:],
++            stdout=open(os.devnull, 'wb'))
++
++    except subprocess.CalledProcessError as e:
++        print("loudgain returned status {}, command was:\n{}".format(
++            e.returncode, subprocess.list2cmdline(e.cmd)), file=sys.stderr)
++        retcode = e.returncode
++
++    except OSError as e:
++        if e.errno == errno.ENOENT:
++            print("loudgain not found, but it is required", file=sys.stderr)
++        else:
++            print("Execution failed:", e, file=sys.stderr)
++        retcode = e.errno
++
++    return retcode
++
++def main():
++    """Main program
++    Usage: rgbpm2 [-h] [-v] folder [folder ...]
++    """
++    # dict: file extension, loudgain cmdline args (use lowercase extensions)
++    # see `loudgain -h` for an explanation of options
++    # '.mp4' deliberately left out: these are doable but usually videos
++    extensions = {
++        '.flac': ['-a', '-k', '-s', 'e'],
++        '.ogg':  ['-a', '-k', '-s', 'e'],
++        '.oga':  ['-a', '-k', '-s', 'e'],
++        '.spx':  ['-a', '-k', '-s', 'e'],
++        '.opus': ['-a', '-k', '-s', 'e'],
++        '.mp2':  ['-I', '3', '-S', '-L', '-a', '-k', '-s', 'e'],
++        '.mp3':  ['-I', '3', '-S', '-L', '-a', '-k', '-s', 'e'],
++        '.m4a':  ['-L', '-a', '-k', '-s', 'e'],
++        '.wma':  ['-L', '-a', '-k', '-s', 'e'],
++        '.asf':  ['-L', '-a', '-k', '-s', 'e'],
++        '.wav':  ['-I', '3', '-L', '-a', '-k', '-s', 'e'],
++        '.aif':  ['-I', '3', '-L', '-a', '-k', '-s', 'e'],
++        '.aiff': ['-I', '3', '-L', '-a', '-k', '-s', 'e'],
++        '.wv':   ['-S', '-a', '-k', '-s', 'e'],
++        '.ape':  ['-S', '-a', '-k', '-s', 'e']
++    }
++
++    # exclude all folders ending in '[compilations]'
++    # special characters masked in [] (glob/fnmatch syntax)
++    excludes = ['*[[]compilations[]]']
++
++    parser = argparse.ArgumentParser(
++        description='ReplayGain album folders recursively, using loudgain.\n' 
+
++            'Files of the same type in the same folder are '
++            'considered an album.\n \n' +
++            textwrap.fill("Supported audio file types: " +
++                ", ".join(sorted(extensions)), 75),
++        epilog='Please report any issues to '
++            'https://github.com/Moonbase59/loudgain/issues.',
++        formatter_class=argparse.RawDescriptionHelpFormatter)
++    parser.add_argument('-v', '--version', action='version',
++        version='%(prog)s ' + __version__)
++    parser.add_argument('-n', '--numproc', type=int, choices=range(1, 33),
++        metavar='1..32', default=multiprocessing.cpu_count(),
++        help='set max. number of parallel processes (default: %(default)d)')
++    parser.add_argument('-f', '--follow-links', action='store_true',
++        help='follow links (default: %(default)s); use with care!')
++    parser.add_argument('folder', nargs='+',
++        help='Path of a folder of audio files.')
++    args = parser.parse_args()
++
++    # set number of parallel processes to use
++    numproc = min(args.numproc, multiprocessing.cpu_count())
++
++    # First, check if loudgain exists and show some info
++    try:
++        output = subprocess.check_output(["loudgain", "--version"],
++            stderr=subprocess.STDOUT)
++        print("Using loudgain v{}, max. {} parallel processes.".format(
++            output.split()[1], numproc))
++    except OSError as e:
++        if e.errno == errno.ENOENT:
++            # handle file not found error.
++            print("loudgain executable not found; this is required",
++                file=sys.stderr)
++            exit(1)
++        else:
++            # Something else went wrong while trying to run `loudgain`
++            raise
++
++    # Traverse folders, set up list of files.
++    # dict: {folder: {filetype: [files]}}
++    cluster = dict()
++    for folder in args.folder:
++        for root, dirs, files in os.walk(os.path.abspath(os.path.join(
++            os.getcwd(), folder)), followlinks=args.follow_links, 
topdown=True):
++            # remove excluded dirs "in-place", only if topdown=True (default)
++            for exclude in excludes:
++                for dir in dirs:
++                    if fnmatch.fnmatch(dir, exclude):
++                        print("Excluding  {}".format(os.path.join(root, dir)))
++                        dirs.remove(dir)
++            # add files with known extensions to cluster
++            for file in files:
++                fileName, fileExt = os.path.splitext(file)
++                if fileExt.lower() in extensions:
++                    cluster.setdefault(root, {}).setdefault(fileExt.lower(),
++                        []).append(file)
++
++    # set up the tasks for multiprocesssing
++    # a task is one loudgain invocation (one folder, same file type)
++    tasks = []
++    for folder in cluster:
++        for ext in cluster[folder]:
++            filelist = []
++            for file in cluster[folder][ext]:
++                filelist.append(os.path.join(folder, file))
++            tasks.append([folder] + [ext] + extensions[ext] + filelist)
++
++    # Set up the parallel task pool
++    # The initializer function prevents child processes from being aborted
++    # by KeyboardInterrupt (Ctrl+C).
++    pool = multiprocessing.Pool(processes=numproc, initializer=init_worker)
++
++    # Run the jobs
++    # The key magic is that we must call results.get() with a timeout, because
++    # a Condition.wait() without a timeout swallows KeyboardInterrupts.
++    results = pool.map_async(loudgain, tasks)
++
++    while not results.ready():
++        try:
++            results.wait(timeout=1)
++        except KeyboardInterrupt:
++            pool.terminate()
++            pool.join()
++            print("KeyboardInterrupt, all processes aborted!", 
file=sys.stderr)
++            exit(1)
++
++    # print(results.get())
++    if not all(ret == 0 for ret in results.get()):
++        print("Errors occurred!", file=sys.stderr)
++
++
++__version_info__ = ('0', '14')
++__version__ = '.'.join(__version_info__)
++
++APPNAME = "rgbpm2 " + __version__
++LICENSE = "MIT"
++
++if __name__ == '__main__':
++    main()
+
+https://github.com/Moonbase59/loudgain/commit/41311d5a889aeb40f83fa4283f152d9e23e53a67
+From 41311d5a889aeb40f83fa4283f152d9e23e53a67 Mon Sep 17 00:00:00 2001
+From: Moonbase59 <[email protected]>
+Date: Thu, 31 Oct 2019 00:37:59 +0100
+Subject: [PATCH] Flush prints to stdout so they're not buffered
+
+---
+ bin/rgbpm2 | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/bin/rgbpm2 b/bin/rgbpm2
+index 0080a9a..4c47fea 100755
+--- a/bin/rgbpm2
++++ b/bin/rgbpm2
+@@ -29,6 +29,7 @@ def loudgain(args):
+     """
+     print("Working on {} ...".format(os.path.abspath(os.path.join(args[0],
+         '*' + args[1]))))
++    sys.stdout.flush()
+     try:
+         retcode = subprocess.check_call(['loudgain', '-q'] + args[2:],
+             stdout=open(os.devnull, 'wb'))
+@@ -105,6 +106,7 @@ def main():
+             stderr=subprocess.STDOUT)
+         print("Using loudgain v{}, max. {} parallel processes.".format(
+             output.split()[1], numproc))
++        sys.stdout.flush()
+     except OSError as e:
+         if e.errno == errno.ENOENT:
+             # handle file not found error.
+@@ -126,6 +128,7 @@ def main():
+                 for dir in dirs:
+                     if fnmatch.fnmatch(dir, exclude):
+                         print("Excluding  {}".format(os.path.join(root, dir)))
++                        sys.stdout.flush()
+                         dirs.remove(dir)
+             # add files with known extensions to cluster
+             for file in files:

diff --git a/media-sound/loudgain/loudgain-0.6.8_p20240128-r3.ebuild 
b/media-sound/loudgain/loudgain-0.6.8_p20240128-r3.ebuild
new file mode 100644
index 0000000000..d28ed69bf3
--- /dev/null
+++ b/media-sound/loudgain/loudgain-0.6.8_p20240128-r3.ebuild
@@ -0,0 +1,47 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake
+
+MY_PV="$(ver_cut 1-3)"
+MY_P="${PN}-${MY_PV}"
+DESCRIPTION="Versatile ReplayGain 2.0 loudness normalizer"
+HOMEPAGE="https://github.com/Moonbase59/loudgain";
+SRC_URI="https://github.com/Moonbase59/${PN}/archive/v${MY_PV}.tar.gz -> 
${MY_P}.tar.gz"
+S="${WORKDIR}/${MY_P}"
+
+LICENSE="BSD-2"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+#REQUIRED_USE=""
+
+COMMON_DEPEND="
+       media-video/ffmpeg:=
+       media-libs/libebur128
+       media-libs/taglib
+"
+RDEPEND="${COMMON_DEPEND}"
+DEPEND="${COMMON_DEPEND}"
+
+PATCHES=(
+       "${FILESDIR}/loudgain-0.6.8-github-20190906-manpage-ape.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-20190918-taglib-1.12.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-20190930-rgbpm2.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-pr34-manpage.patch"
+       # Bug 922026
+       "${FILESDIR}/loudgain-0.6.8-github-pr50-ffmpeg6.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-pr53-print-taglib-version.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-pr65-ffmpeg6-gcc14.patch"
+       "${FILESDIR}/loudgain-0.6.8-github-pr66-ffmpeg7.patch"
+       "${FILESDIR}/loudgain-0.6.8-respect-build-flags.patch"
+       # Bug 951350
+       "${FILESDIR}/loudgain-0.6.8-cmake-4.patch"
+)
+
+src_install() {
+       cmake_src_install
+       dobin bin/rgbpm2
+       dodoc README.md
+}

Reply via email to