Bind Android smoke to build provenance and actual PCM assertions
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
param([Parameter(Mandatory)][string]$OutputPath, [int]$Seconds=15, [int]$Port=8554)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Add-Type -TypeDefinition @'
|
||||
using System;
|
||||
public static class AndroidPcmLevels {
|
||||
public static double[] Measure(byte[] bytes) {
|
||||
double sum=0, peak=0; int active=0;
|
||||
for(int i=0;i+1<bytes.Length;i+=2) { int sample=(short)(bytes[i] | (bytes[i+1]<<8)); sum+=(double)sample*sample; peak=Math.Max(peak,Math.Abs(sample)); if(Math.Abs(sample)>32) active++; }
|
||||
return new[]{peak, bytes.Length>0 ? Math.Sqrt(sum/(bytes.Length/2)) : 0, (double)active};
|
||||
}
|
||||
}
|
||||
'@
|
||||
# EmulatorController.streamAudio의 PCM을 직접 기록합니다. 제품 APK에는 포함되지 않습니다.
|
||||
# wire schema: Android SDK emulator/lib/emulator_controller.proto.
|
||||
[AppContext]::SetSwitch('System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport', $true)
|
||||
@@ -19,11 +29,13 @@ $request.Content.Headers.ContentType = [Net.Http.Headers.MediaTypeHeaderValue]::
|
||||
$cancel = [Threading.CancellationTokenSource]::new([TimeSpan]::FromSeconds($Seconds))
|
||||
$pcm = [IO.MemoryStream]::new()
|
||||
$packets = 0
|
||||
$startedUtc=[DateTime]::UtcNow.ToString('o')
|
||||
$firstPacketTimestamp=$null; $lastPacketTimestamp=$null
|
||||
function Read-Exactly($Stream,[int]$Length) {
|
||||
$bytes = [byte[]]::new($Length)
|
||||
$offset=0
|
||||
while ($offset -lt $Length) {
|
||||
$n=$Stream.ReadAsync($bytes.AsMemory($offset,$Length-$offset),$cancel.Token).AsTask().GetAwaiter().GetResult()
|
||||
$n=$Stream.ReadAsync($bytes,$offset,$Length-$offset,$cancel.Token).GetAwaiter().GetResult()
|
||||
if ($n -eq 0) { throw 'gRPC 오디오 스트림이 끝났습니다.' }
|
||||
$offset += $n
|
||||
}
|
||||
@@ -42,13 +54,13 @@ try {
|
||||
while (!$cancel.IsCancellationRequested) {
|
||||
$header=Read-Exactly $stream 5
|
||||
if ($header[0] -ne 0) { throw '압축 gRPC 프레임은 지원하지 않습니다.' }
|
||||
$length=($header[1] -shl 24) -bor ($header[2] -shl 16) -bor ($header[3] -shl 8) -bor $header[4]
|
||||
$length=([int]$header[1] -shl 24) -bor ([int]$header[2] -shl 16) -bor ([int]$header[3] -shl 8) -bor [int]$header[4]
|
||||
$message=Read-Exactly $stream $length
|
||||
$i=0
|
||||
while ($i -lt $message.Length) {
|
||||
$tag=Read-Varint $message ([ref]$i)
|
||||
switch ($tag -band 7) {
|
||||
0 { $null=Read-Varint $message ([ref]$i) }
|
||||
0 { $value=Read-Varint $message ([ref]$i); if (($tag -shr 3) -eq 2) { if ($null -eq $firstPacketTimestamp) { $firstPacketTimestamp=$value }; $lastPacketTimestamp=$value } }
|
||||
2 {
|
||||
$size=Read-Varint $message ([ref]$i)
|
||||
if (($tag -shr 3) -eq 3) { $pcm.Write($message,$i,$size); $packets++ }
|
||||
@@ -62,6 +74,7 @@ try {
|
||||
if (!$cancel.IsCancellationRequested) { throw }
|
||||
} finally {
|
||||
$data=$pcm.ToArray()
|
||||
$levels=[AndroidPcmLevels]::Measure($data)
|
||||
$file=[IO.File]::Create($OutputPath)
|
||||
$writer=[IO.BinaryWriter]::new($file)
|
||||
try {
|
||||
@@ -69,7 +82,7 @@ try {
|
||||
$writer.Write([int]16); $writer.Write([int16]1); $writer.Write([int16]1); $writer.Write([int]24000); $writer.Write([int]48000); $writer.Write([int16]2); $writer.Write([int16]16);
|
||||
$writer.Write([Text.Encoding]::ASCII.GetBytes('data')); $writer.Write([int]$data.Length); $writer.Write($data)
|
||||
} finally { $writer.Dispose(); $file.Dispose(); $client.Dispose(); $cancel.Dispose(); $pcm.Dispose() }
|
||||
[ordered]@{ method='EmulatorController.streamAudio'; endpoint="127.0.0.1:$Port"; packets=$packets; pcmBytes=$data.Length; sampleRate=24000; channels=1; bitsPerSample=16; auditoryReview=$false } |
|
||||
[ordered]@{ method='EmulatorController.streamAudio'; endpoint="127.0.0.1:$Port"; sourceCommit=(& git rev-parse HEAD); sourceDirty=[bool](& git status --porcelain); startedUtc=$startedUtc; finishedUtc=[DateTime]::UtcNow.ToString('o'); firstDevicePacketTimestampUs=$firstPacketTimestamp; lastDevicePacketTimestampUs=$lastPacketTimestamp; packets=$packets; pcmBytes=$data.Length; sampleRate=24000; channels=1; bitsPerSample=16; peakPcm=$levels[0]; rmsPcm=$levels[1]; nonSilentSamples=$levels[2]; auditoryReview=$false } |
|
||||
ConvertTo-Json | Set-Content -LiteralPath ($OutputPath + '.json') -Encoding utf8
|
||||
}
|
||||
if ($packets -eq 0) { throw '실제 오디오 패킷을 받지 못했습니다.' }
|
||||
|
||||
Reference in New Issue
Block a user