88 lines
3 KiB
C#
88 lines
3 KiB
C#
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);
|
|
}
|
|
}
|