Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04-arm, ubuntu-24.04, ubuntu-22.04, windows-2022, windows-2019, macos-15, macos-14, macos-13]
os: [ubuntu-24.04-arm, ubuntu-24.04, ubuntu-22.04, windows-2025, windows-2022, macos-15, macos-14, macos-13]
python: ['3.13', '3.10']
defaults:
run:
Expand All @@ -31,11 +31,9 @@ jobs:
- run: pip install sounddevice
- run: python -m sounddevice
- run: |
set -xeo pipefail
python -m sounddevice | grep "[82] out"
name: Check that there is some output device
- run: sleep 10

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the sleep in there? There must have been a reason we put it in there sleep at some point (I don't remember what it is offhand) so probably better to keep it and do the check twice.

Also the existing test made sure that there were actually output channels available, the test no longer does that. Looks like the output on Windows is:

<  4 Speakers (2- VB-Audio Virtual C, MME (0 in, 8 out)

so it should have still passed. So it's probably worth reverting these changes, or otherwise refactoring them to make sure they still check things as completely as they did before.

- run: |
set -xeo pipefail
python -m sounddevice | grep "[82] out"
name: Check that there is some output device after sleep
output=$(python -m sounddevice --list-devices)
if [ -z "$output" ]; then
echo "Error: sounddevice --list-devices returned no output"
exit 1
fi
echo "$output"
99 changes: 67 additions & 32 deletions windows/setup_sound.ps1
Original file line number Diff line number Diff line change
@@ -1,38 +1,73 @@
# Someday if this breaks we can use:
# https://github.com/duncanthrax/scream/tree/master/Install
# But it signs using a SHA that is buggy with Windows 7 so don't use for now
# https://support.microsoft.com/en-us/help/2921916/the-untrusted-publisher-dialog-box-appears-when-you-install-a-driver-i
function DownloadVirtualSoundcard () {
$webclient = New-Object System.Net.WebClient
$url = "https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack43.zip"
$filepath = $pwd.Path + "\vbcable.zip"
Write-Host "Downloading" $url
$retry_attempts = 2
for($i=0; $i -lt $retry_attempts; $i++){
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
param (
[string]$Url = 'https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack45.zip',
[string]$ZipName = 'vbcable.zip',
[string]$ExtractDir = 'vbcable'
)

function Download-Zip {
param($Url, $Out)
Write-Host "Downloading $Url → $Out"
$wc = New-Object System.Net.WebClient
0..2 | ForEach-Object {
try { $wc.DownloadFile($Url, $Out); return } catch { Start-Sleep 1 }
}
$wc.DownloadFile($Url, $Out)
}

function Expand-Zip {
param($Zip, $Dest)
Write-Host "Extracting $Zip → $Dest"
Expand-Archive -LiteralPath $Zip -DestinationPath $Dest -Force
}

function Trust-Cert {
param($Cer)
Write-Host "Adding certificate to TrustedPublisher: $Cer"
certutil -addstore -f TrustedPublisher $Cer
}

function Install-Driver {
param($InfDir)
Write-Host "Installing driver(s) from $InfDir"
Get-ChildItem -Path $InfDir -Filter 'vbMmeCable64_win*.inf' -Recurse |
ForEach-Object {
$inf = $_.FullName
Write-Host " devcon.exe install `"$inf`" VBAudioVACWDM"
& "$PSScriptRoot\devcon.exe" install "$inf" VBAudioVACWDM
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}

function Restart-AudioServices {
Write-Host "Restarting Audio services to pick up new device"
foreach ($svc in 'AudioSrv','AudioEndpointBuilder') {
if (Get-Service $svc -ErrorAction SilentlyContinue) {
Restart-Service -Name $svc -Force
}
}
}

function main () {
Push-Location $PSScriptRoot
DownloadVirtualSoundcard
Expand-Archive -LiteralPath vbcable.zip -DestinationPath vbcable
certutil -addstore "TrustedPublisher" vbcable.cer
# PnPutil.exe -i -a vbcable/vbMmeCable64_win7.inf
.\devcon.exe install vbcable\vbMmeCable64_win7.inf VBAudioVACWDM
Pop-location
function Dump-Devices {
Write-Host "Current sound devices:"
Get-CimInstance Win32_SoundDevice |
Select-Object Name,Status |
Format-Table -AutoSize
}

main
Push-Location $PSScriptRoot

Download-Zip -Url $Url -Out (Join-Path $PSScriptRoot $ZipName)
Expand-Zip -Zip (Join-Path $PSScriptRoot $ZipName) -Dest (Join-Path $PSScriptRoot $ExtractDir)

$cer = Join-Path $PSScriptRoot 'vbcable.cer'
if (Test-Path $cer) {
Write-Host "Adding certificate to TrustedPublisher: $cer"
certutil.exe -addstore -f TrustedPublisher $cer
} else {
Write-Error "Certificate not found at $cer; cannot trust the driver."
}
Install-Driver -InfDir (Join-Path $PSScriptRoot $ExtractDir)

Restart-AudioServices
Dump-Devices

Pop-Location