using System; using Paca.Core; using Xunit; namespace Paca.Tests.Core; public class AudioVolumeNormalizerGateTests { [Fact] public void Gate301_AudioVolumeNormalizer_ProvidesStandardTargetPresets() { var streaming = AudioVolumeNormalizer.PodcastStreamingPreset; Assert.Equal(-16.0, streaming.TargetI); Assert.Equal(-1.0, streaming.TargetTp); Assert.Equal(11.0, streaming.TargetLra); var ebu = AudioVolumeNormalizer.StandardEbuR128Preset; Assert.Equal(-23.0, ebu.TargetI); Assert.Equal(-1.0, ebu.TargetTp); Assert.Equal(7.0, ebu.TargetLra); var night = AudioVolumeNormalizer.NightModeCompressedPreset; Assert.Equal(-20.0, night.TargetI); Assert.Equal(-2.0, night.TargetTp); Assert.Equal(5.0, night.TargetLra); } [Fact] public void Gate302_AudioVolumeNormalizer_BuildsFilterArgs_Accurately() { var preset = AudioVolumeNormalizer.PodcastStreamingPreset; var filter = AudioVolumeNormalizer.BuildLoudnormFilterArgs(preset); Assert.Equal("loudnorm=I=-16.0:TP=-1.0:LRA=11.0", filter); } [Fact] public void Gate303_AudioVolumeNormalizer_BuildsCommandLine_WithVideoPassthrough() { var preset = AudioVolumeNormalizer.PodcastStreamingPreset; var cmd = AudioVolumeNormalizer.BuildNormalizeCommandLine( inputPath: "C:\\videos\\clip.mp4", outputPath: "C:\\videos\\clip_normalized.mp4", preset: preset, copyVideo: true ); Assert.Contains("-i \"C:\\videos\\clip.mp4\"", cmd); Assert.Contains("-c:v copy", cmd); Assert.Contains("-filter:a \"loudnorm=I=-16.0:TP=-1.0:LRA=11.0\"", cmd); Assert.Contains("-c:a aac -b:a 192k", cmd); Assert.EndsWith("\"C:\\videos\\clip_normalized.mp4\" -y", cmd); } [Fact] public void Gate304_AudioVolumeNormalizer_ParsesFirstPassStats_AndBuildsSecondPassFilter() { var ffmpegFirstPassOutput = @" [Parsed_loudnorm_0 @ 0000021c1c68f140] { ""input_i"" : ""-28.52"", ""input_tp"" : ""-4.12"", ""input_lra"" : ""9.30"", ""input_thresh"" : ""-39.10"", ""output_i"" : ""-16.12"", ""output_tp"" : ""-1.00"", ""output_lra"" : ""7.80"", ""output_thresh"" : ""-26.65"", ""normalization_type"" : ""dynamic"", ""target_offset"" : ""0.12"" } "; var stats = AudioVolumeNormalizer.ParseLoudnormFirstPassStats(ffmpegFirstPassOutput); Assert.NotNull(stats); Assert.Equal(-28.52, stats!.InputI); Assert.Equal(-4.12, stats.InputTp); Assert.Equal(9.30, stats.InputLra); Assert.Equal(-39.10, stats.InputThresh); Assert.Equal(0.12, stats.TargetOffset); var preset = AudioVolumeNormalizer.PodcastStreamingPreset; var secondPassFilter = AudioVolumeNormalizer.BuildSecondPassFilterArgs(preset, stats); Assert.Equal("loudnorm=I=-16.0:TP=-1.0:LRA=11.0:measured_I=-28.52:measured_TP=-4.12:measured_LRA=9.30:measured_thresh=-39.10:offset=0.12:linear=true", secondPassFilter); } }