test(content): verify native Android PCM and complete speech coverage
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
param([Parameter(Mandatory)][string]$ReferencePath, [Parameter(Mandatory)][string]$CapturedPath, [Parameter(Mandatory)][string]$OutputPath)
|
||||
param([Parameter(Mandatory)][string]$ReferencePath, [Parameter(Mandatory)][string]$CapturedPath, [Parameter(Mandatory)][string]$OutputPath, [switch]$RequireFullSpeech)
|
||||
$ErrorActionPreference='Stop'
|
||||
Add-Type -TypeDefinition @'
|
||||
using System;
|
||||
@@ -46,6 +46,19 @@ public static class AndroidPcmComparison {
|
||||
double fullCorrelation=fullDot/Math.Sqrt(sourceEnergy*outputEnergy);
|
||||
return new[]{fullCorrelation,bestLag/24000.0,source.Length/24000.0,output.Length/24000.0,Math.Sqrt(outputEnergy/source.Length),fullDot/sourceEnergy,(double)nonzero};
|
||||
}
|
||||
public static double[] Coverage(string original,string captured,double onset) {
|
||||
var source=Read(original); var output=Read(captured); int lag=(int)Math.Round(onset*24000),window=2400,step=1200;
|
||||
if(source.Length<window || lag<0 || lag+source.Length>output.Length) throw new Exception("Complete speech coverage data required");
|
||||
int tested=0,failed=0; double minimum=1;
|
||||
for(int offset=0;;offset=Math.Min(offset+step,source.Length-window)) {
|
||||
double dot=0,se=0,oe=0;
|
||||
for(int j=0;j<window;j++) { double s=source[offset+j],o=output[lag+offset+j]; dot+=s*o;se+=s*s;oe+=o*o; }
|
||||
// Same PCM32 activity floor as the existing capture check; never omit a quiet speech window by raising it.
|
||||
if(Math.Sqrt(se/window)>=32) { double c=oe>0 ? dot/Math.Sqrt(se*oe) : 0; tested++;minimum=Math.Min(minimum,c);if(c<0.95)failed++; }
|
||||
if(offset==source.Length-window) break;
|
||||
}
|
||||
return new[]{(double)tested,minimum,(double)failed};
|
||||
}
|
||||
}
|
||||
'@
|
||||
$values=[AndroidPcmComparison]::Compare((Resolve-Path -LiteralPath $ReferencePath).Path,(Resolve-Path -LiteralPath $CapturedPath).Path)
|
||||
@@ -53,6 +66,12 @@ $passed=$values[0] -ge 0.95 -and $values[4] -gt 32 -and $values[6] -gt 100
|
||||
$record=[ordered]@{ reference=$ReferencePath; referenceSha256=(Get-FileHash -LiteralPath $ReferencePath -Algorithm SHA256).Hash;
|
||||
captured=$CapturedPath; capturedSha256=(Get-FileHash -LiteralPath $CapturedPath -Algorithm SHA256).Hash;
|
||||
normalizedCorrelation=$values[0]; onsetSeconds=$values[1]; referenceDurationSeconds=$values[2]; capturedDurationSeconds=$values[3]; rmsPcm=$values[4]; gain=$values[5]; nonSilentSamples=$values[6]; thresholdCorrelation=0.95; passed=$passed; auditoryReview=$false }
|
||||
if ($RequireFullSpeech) {
|
||||
$coverage=[AndroidPcmComparison]::Coverage((Resolve-Path -LiteralPath $ReferencePath).Path,(Resolve-Path -LiteralPath $CapturedPath).Path,$values[1])
|
||||
$record.requireFullSpeech=$true;$record.speechWindowMilliseconds=100;$record.speechStepMilliseconds=50;$record.sourceActivityRmsPcm=32
|
||||
$record.speechWindows=$coverage[0];$record.minimumSpeechCorrelation=$coverage[1];$record.failedSpeechWindows=$coverage[2]
|
||||
$passed=$passed -and $coverage[0] -gt 0 -and $coverage[2] -eq 0;$record.passed=$passed
|
||||
}
|
||||
$record | ConvertTo-Json | Set-Content -LiteralPath $OutputPath -Encoding utf8
|
||||
Write-Host "실제 PCM 대조: 상관 $($values[0]), 비무음 샘플 $($values[6]), 통과 $passed"
|
||||
if (!$passed) { exit 1 }
|
||||
|
||||
Reference in New Issue
Block a user