jackailocal / windows /Install-Voice.ps1
jackboy70's picture
Deploy: accurate lite-builder note
f25362a
Raw
History Blame Contribute Delete
3.59 kB
[CmdletBinding()]
param(
[string]$TargetRoot = ""
)
$ErrorActionPreference = "Stop"
if (-not $TargetRoot) { $TargetRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path }
if (!(Test-Path $TargetRoot)) { throw "Target root does not exist: $TargetRoot" }
$TargetRoot = (Resolve-Path $TargetRoot).Path
$assetConfigPath = Join-Path $TargetRoot "config\voice-assets.json"
if (!(Test-Path $assetConfigPath)) { throw "Voice asset configuration is missing: $assetConfigPath" }
$assetConfig = Get-Content -Raw $assetConfigPath | ConvertFrom-Json
$assets = $assetConfig.windows_x64
$shared = $assetConfig.shared
$cache = Join-Path $TargetRoot ".jackailocal-builder\voice-cache"
$whisperDir = Join-Path $TargetRoot "backends\whisper.cpp\windows"
$piperDir = Join-Path $TargetRoot "backends\piper\windows"
$whisperModelDir = Join-Path $TargetRoot "models\whisper"
$piperModelDir = Join-Path $TargetRoot "models\piper"
New-Item -ItemType Directory -Force -Path $cache,$whisperDir,$piperDir,$whisperModelDir,$piperModelDir | Out-Null
function Download-Verified([string]$Url, [string]$Sha256, [string]$Destination) {
if (Test-Path $Destination) {
$existing = (Get-FileHash -Algorithm SHA256 -Path $Destination).Hash.ToLowerInvariant()
if ($existing -eq $Sha256.ToLowerInvariant()) { return }
Remove-Item -LiteralPath $Destination -Force
}
Write-Host "Downloading $Url" -ForegroundColor Cyan
Invoke-WebRequest -Uri $Url -OutFile $Destination -UseBasicParsing
$actual = (Get-FileHash -Algorithm SHA256 -Path $Destination).Hash.ToLowerInvariant()
if ($actual -ne $Sha256.ToLowerInvariant()) {
Remove-Item -LiteralPath $Destination -Force
throw "SHA256 verification failed for $Url. Expected $Sha256, got $actual."
}
}
function Copy-ArchiveContents([string]$Archive, [string]$Destination, [string]$RequiredFile) {
$extract = Join-Path $cache ([IO.Path]::GetFileNameWithoutExtension($Archive))
if (Test-Path $extract) { Remove-Item -LiteralPath $extract -Recurse -Force }
New-Item -ItemType Directory -Force -Path $extract | Out-Null
Expand-Archive -Path $Archive -DestinationPath $extract -Force
$required = Get-ChildItem -Path $extract -Recurse -File -Filter $RequiredFile | Select-Object -First 1
if (-not $required) { throw "Required file $RequiredFile was not found in $Archive." }
$sourceDir = Split-Path $required.FullName -Parent
Copy-Item -Path (Join-Path $sourceDir "*") -Destination $Destination -Recurse -Force
}
$whisperArchive = Join-Path $cache "whisper-bin-x64.zip"
$piperArchive = Join-Path $cache "piper-windows-amd64.zip"
$whisperModel = Join-Path $whisperModelDir "ggml-base.bin"
$piperVoice = Join-Path $piperModelDir "en_US-libritts_r-medium.onnx"
$piperVoiceConfig = Join-Path $piperModelDir "en_US-libritts_r-medium.onnx.json"
if (!(Test-Path (Join-Path $whisperDir "whisper-cli.exe"))) {
Download-Verified $assets.whisper.archive_url $assets.whisper.archive_sha256 $whisperArchive
Copy-ArchiveContents $whisperArchive $whisperDir "whisper-cli.exe"
}
if (!(Test-Path (Join-Path $piperDir "piper.exe"))) {
Download-Verified $assets.piper.archive_url $assets.piper.archive_sha256 $piperArchive
Copy-ArchiveContents $piperArchive $piperDir "piper.exe"
}
Download-Verified $shared.whisper.model_url $shared.whisper.model_sha256 $whisperModel
Download-Verified $shared.piper.voice_url $shared.piper.voice_sha256 $piperVoice
Download-Verified $shared.piper.voice_config_url $shared.piper.voice_config_sha256 $piperVoiceConfig
Write-Host "Voice assets installed and verified under $TargetRoot" -ForegroundColor Green