Files
MagnetismHeroes/tools/android/test-native-audio.ps1
T

41 lines
3.4 KiB
PowerShell

param([Parameter(Mandatory)][string]$ReferencePath,[Parameter(Mandatory)][string]$CapturedPath,[Parameter(Mandatory)][string]$WrongReferencePath,[Parameter(Mandatory)][string]$EvidenceDir)
$ErrorActionPreference='Stop'
New-Item -ItemType Directory -Path $EvidenceDir -Force | Out-Null
$checks=[Collections.Generic.List[object]]::new()
function Match([string]$Name,[string]$Reference,[string]$Captured,[bool]$Expected) {
$path=Join-Path $EvidenceDir "$Name.json"
& pwsh -NoProfile -File (Join-Path $PSScriptRoot 'compare-audio.ps1') -ReferencePath $Reference -CapturedPath $Captured -OutputPath $path -RequireFullSpeech
$code=$LASTEXITCODE;$record=Get-Content -LiteralPath $path -Raw | ConvertFrom-Json
$checks.Add(@{name=$Name;expectedPassed=$Expected;exitCode=$code;record=$record})
if ($record.passed -ne $Expected -or ($Expected -and $code -ne 0) -or (!$Expected -and $code -eq 0)) { throw "PCM negative control mismatch: $Name" }
return $record
}
try {
$positive=Match 'positive-full-speech' $ReferencePath $CapturedPath $true
Add-Type -TypeDefinition @'
using System;
using System.IO;
public static class NativeAudioControls {
public static void Create(string input,string output,string kind,double onset,double duration) {
byte[] bytes=File.ReadAllBytes(input);int rate=BitConverter.ToInt32(bytes,24),start=(int)Math.Round(onset*rate),length=(int)Math.Round(duration*rate),cut=rate/4,middle=start+(int)(rate*.85);
if(BitConverter.ToInt16(bytes,20)!=1 || BitConverter.ToInt16(bytes,22)!=1 || BitConverter.ToInt16(bytes,34)!=16 || System.Text.Encoding.ASCII.GetString(bytes,36,4)!="data") throw new Exception("Canonical monoPCM16 WAV required");
short[] data=new short[(bytes.Length-44)/2];Buffer.BlockCopy(bytes,44,data,0,bytes.Length-44);
if(start<0 || start+length>data.Length || length<rate)throw new Exception("Complete control speech required");
if(kind=="duplicate") {var longer=new short[data.Length+cut];Array.Copy(data,0,longer,0,middle);Array.Copy(data,middle-cut,longer,middle,cut);Array.Copy(data,middle,longer,middle+cut,data.Length-middle);data=longer;}
else if(kind=="noise") {var random=new Random(42);for(int i=0;i<data.Length;i++)data[i]=(short)random.Next(-4096,4097);}
else {int offset=kind=="front"?start:kind=="back"?start+length-cut:middle;Array.Clear(data,offset,cut);}
using(var w=new BinaryWriter(File.Create(output))) {w.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));w.Write(36+data.Length*2);w.Write(System.Text.Encoding.ASCII.GetBytes("WAVEfmt "));w.Write(16);w.Write((short)1);w.Write((short)1);w.Write(rate);w.Write(rate*2);w.Write((short)2);w.Write((short)16);w.Write(System.Text.Encoding.ASCII.GetBytes("data"));w.Write(data.Length*2);foreach(short sample in data)w.Write(sample);}
}
}
'@
foreach($kind in @('front','back','middle','duplicate','noise')) {
$path=Join-Path $EvidenceDir "$kind.wav";[NativeAudioControls]::Create((Resolve-Path $CapturedPath).Path,$path,$kind,$positive.onsetSeconds,$positive.referenceDurationSeconds)
Match $kind $ReferencePath $path $false | Out-Null
}
Match 'wrong-clip' $WrongReferencePath $CapturedPath $false | Out-Null
$passed=$true
} finally {
@{sourceCommit=(& git rev-parse HEAD);sourceDirty=[bool](& git status --porcelain);passed=($passed -eq $true);checks=$checks.ToArray();finishedUtc=[DateTime]::UtcNow.ToString('o')} | ConvertTo-Json -Depth 8 | Set-Content (Join-Path $EvidenceDir 'regression.json') -Encoding utf8
}
Write-Host 'Native PCM positive and six meaningful negative controls passed.'