using System; using System.Collections.Generic; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Core; /// /// Gate 199 ~ 202: 오디오 파형 시각화 및 스마트 무음 건너뛰기(Smart Silence Skipper) 기계적 검증 /// public class SmartSilenceSkipperAndWaveformGateTests { [Fact] public void Gate199_AudioWaveform_Downsampling_And_Peaks() { // 100개의 가상 PCM 오디오 샘플 (0.0 ~ 1.0) var samples = new float[100]; for (int i = 0; i < 50; i++) samples[i] = 0.01f; // 전반부 무음 for (int i = 50; i < 100; i++) samples[i] = 0.8f; // 후반부 강한 음성 var peaks = AudioWaveformGenerator.GeneratePeaks(samples, targetBarCount: 10); Assert.Equal(10, peaks.Count); // 전반부 피크는 낮고 Assert.True(peaks[0] < 0.1f); // 후반부 피크는 높음 Assert.True(peaks[9] > 0.7f); } [Fact] public void Gate200_SmartSilenceSkipper_Detects_Silence_Interval() { var intervals = new List { new(TimeSpan.Zero, TimeSpan.FromSeconds(10), IsSilence: false), new(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), IsSilence: true), // 5초 무음 new(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30), IsSilence: false) }; var skipper = new SmartSilenceSkipper(intervals); // 현재 11초 위치(무음 구간) -> 15초(다음 음성)로 즉각 스킵 제안 var skipTarget = skipper.GetNextSpeechPosition(TimeSpan.FromSeconds(11)); Assert.Equal(TimeSpan.FromSeconds(15), skipTarget); // 현재 5초 위치(음성 구간) -> 스킵 불필요(원위치 유지) var normalTarget = skipper.GetNextSpeechPosition(TimeSpan.FromSeconds(5)); Assert.Equal(TimeSpan.FromSeconds(5), normalTarget); } [Fact] public void Gate201_SmartSilenceSkipper_Accumulates_SavedTime() { var intervals = new List { new(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), IsSilence: true), // 5초 new(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(38), IsSilence: true) // 8초 }; var skipper = new SmartSilenceSkipper(intervals); skipper.RecordSkip(TimeSpan.FromSeconds(5)); skipper.RecordSkip(TimeSpan.FromSeconds(8)); Assert.Equal(TimeSpan.FromSeconds(13), skipper.TotalSavedTime); Assert.Equal("13초 절약됨", skipper.FormatSavedTime()); } [Fact] public void Gate202_AudioWaveform_Serialization_Integrity() { var original = new AudioWaveformData(new float[] { 0.1f, 0.5f, 0.9f, 0.3f }); var encoded = original.ToBase64String(); var restored = AudioWaveformData.FromBase64String(encoded); Assert.Equal(original.Peaks.Count, restored.Peaks.Count); for (int i = 0; i < original.Peaks.Count; i++) { Assert.Equal(original.Peaks[i], restored.Peaks[i], precision: 2); } } }