Skip to content

Commit

Permalink
Implement --safe-ebu
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmetsait committed Dec 9, 2024
1 parent 5e50a4f commit 881c765
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
17 changes: 17 additions & 0 deletions ffmpeg_normalize/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,22 @@ def create_parser() -> argparse.ArgumentParser:
),
)

group_ebu.add_argument(
"--safe-ebu",
type=float,
help=textwrap.dedent(
"""\
Automatically lower EBU Integrated Loudness Target to prevent falling
back to dynamic filtering. (default: 0.0)
Makes sure target loudness is lower than measured loudness minus peak
loudness (input_i - input_tp) by the given amount. A value of 0 means
disabled.
"""
),
default=0.0,
)

group_ebu.add_argument(
"--dual-mono",
action="store_true",
Expand Down Expand Up @@ -529,6 +545,7 @@ def _split_options(opts: str) -> list[str]:
true_peak=cli_args.true_peak,
offset=cli_args.offset,
lower_only=cli_args.lower_only,
safe_ebu=cli_args.safe_ebu,
dual_mono=cli_args.dual_mono,
dynamic=cli_args.dynamic,
audio_codec=cli_args.audio_codec,
Expand Down
3 changes: 3 additions & 0 deletions ffmpeg_normalize/_ffmpeg_normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class FFmpegNormalize:
true_peak (float, optional): True peak. Defaults to -2.0.
offset (float, optional): Offset. Defaults to 0.0.
lower_only (bool, optional): Whether the audio should not increase in loudness. Defaults to False.
safe_ebu (float, optional): Safe EBU. Defaults to 0.0.
dual_mono (bool, optional): Dual mono. Defaults to False.
dynamic (bool, optional): Dynamic. Defaults to False.
audio_codec (str, optional): Audio codec. Defaults to "pcm_s16le".
Expand Down Expand Up @@ -98,6 +99,7 @@ def __init__(
true_peak: float = -2.0,
offset: float = 0.0,
lower_only: bool = False,
safe_ebu: float = 0.0,
dual_mono: bool = False,
dynamic: bool = False,
audio_codec: str = "pcm_s16le",
Expand Down Expand Up @@ -169,6 +171,7 @@ def __init__(
self.true_peak = check_range(true_peak, -9, 0, name="true_peak")
self.offset = check_range(offset, -99, 99, name="offset")
self.lower_only = lower_only
self.safe_ebu = safe_ebu

# Ensure library user is passing correct types
assert isinstance(dual_mono, bool), "dual_mono must be bool"
Expand Down
18 changes: 17 additions & 1 deletion ffmpeg_normalize/_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,26 @@ def get_second_pass_opts_ebu(self) -> str:
"Specify -ar/--sample-rate to override it."
)

target_level = self.ffmpeg_normalize.target_level
if self.ffmpeg_normalize.safe_ebu > 0:
safe_target = (
self.loudness_statistics["ebu_pass1"]["input_i"]
- self.loudness_statistics["ebu_pass1"]["input_tp"]
+ self.ffmpeg_normalize.true_peak
- self.ffmpeg_normalize.safe_ebu
)
if safe_target < self.ffmpeg_normalize.target_level:
_logger.warning(
"Using loudness target %s because --safe-ebu=%s.",
safe_target,
self.ffmpeg_normalize.safe_ebu,
)
target_level = safe_target

stats = self.loudness_statistics["ebu_pass1"]

opts = {
"i": self.media_file.ffmpeg_normalize.target_level,
"i": target_level,
"lra": self.media_file.ffmpeg_normalize.loudness_range_target,
"tp": self.media_file.ffmpeg_normalize.true_peak,
"offset": self._constrain(
Expand Down

0 comments on commit 881c765

Please sign in to comment.