Compare commits

...

4 Commits

Author SHA1 Message Date
bd0779add2 add Taskfile
upd tasks in launch.json

add with Task to Run tests in README
2025-06-06 13:50:16 +01:00
a0a2c72634 run through formatter
rename pre-commit to run

remove num and log parameters
2025-06-06 13:49:35 +01:00
0f68a2373d run through formatter 2025-06-06 13:48:24 +01:00
2d6437d37b run through formatter 2025-06-06 13:48:11 +01:00
23 changed files with 237 additions and 285 deletions

5
.gitignore vendored
View File

@ -1,7 +1,6 @@
# quick test
quick.ps1
lib/*.psd1 lib/*.psd1
**/*.log **/*.log
config.psd1 config.psd1
test-*.ps1

14
.vscode/launch.json vendored
View File

@ -51,21 +51,9 @@
"type": "PowerShell", "type": "PowerShell",
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"script": "${workspaceFolder}/tests/pre-commit.ps1", "script": "${workspaceFolder}/tests/run.ps1",
"args": [], "args": [],
"createTemporaryIntegratedConsole": true "createTemporaryIntegratedConsole": true
}, },
{
"name": "PowerShell: Launch Quick Test",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}",
"script": "${workspaceFolder}/quick.ps1",
"args": [
"-Verbose",
"-Debug"
],
"createTemporaryIntegratedConsole": true
}
] ]
} }

View File

@ -557,16 +557,16 @@ Access to lower level polling functions are provided with these functions:
### Run tests ### Run tests
Run tests using .\tests\pre-commit.ps1 which accepts the following parameters: Parameters:
- `kind`: Run tests of this kind - `kind`: Run tests of this kind
- `tag`: Run tests tagged with this marker (currently `higher` or `lower`) - `tag`: Run tests tagged with this marker (currently `higher` or `lower`)
- `num`: Run this number of tests
- `log`: Write summary log file
Run tests from repository root in a subshell and write logs, like so: *with Task*
`powershell .\tests\pre-commit.ps1 -k "potato" -t "higher" -log` ```console
task test -- -t "higher" -k "banana"
```
### Official Documentation ### Official Documentation

11
Taskfile.yaml Normal file
View File

@ -0,0 +1,11 @@
version: '3'
tasks:
test:
desc: 'Run tests'
preconditions:
- sh: 'pwsh -c "if ([System.Version](Get-InstalledModule Pester).Version.ToString() -gt [System.Version]"5.7.0") { exit 0 } else { exit 1 }"'
msg: 'Pester version must be greater than 5.7.0'
cmds:
- echo "Running tests..."
- pwsh -c "tests\run.ps1 {{.CLI_ARGS}}"

View File

@ -1,7 +1,7 @@
[cmdletbinding()] [cmdletbinding()]
param( param(
[switch]$interactive, [switch]$interactive,
[String]$kind = "banana", [String]$kind = 'banana',
[String[]]$script = @() [String[]]$script = @()
) )
@ -20,20 +20,20 @@ function get-value {
function msgHandler { function msgHandler {
param([object]$vmr, [string]$line) param([object]$vmr, [string]$line)
$line + " passed to handler" | Write-Debug $line + ' passed to handler' | Write-Debug
if ($line[0] -eq "!") { if ($line[0] -eq '!') {
"Toggling " + $line.substring(1) | Write-Debug 'Toggling ' + $line.substring(1) | Write-Debug
$retval = get-value -vmr $vmr -line $line.substring(1) $retval = get-value -vmr $vmr -line $line.substring(1)
$vmr.Setter($line.substring(1), 1 - $retval) $vmr.Setter($line.substring(1), 1 - $retval)
} }
elseif ($line.Contains("=")) { elseif ($line.Contains('=')) {
"Setting $line" | Write-Debug "Setting $line" | Write-Debug
$vmr.SendText($line) $vmr.SendText($line)
} }
else { else {
"Getting $line" | Write-Debug "Getting $line" | Write-Debug
$retval = get-value -vmr $vmr -line $line $retval = get-value -vmr $vmr -line $line
$line + " = " + $retval | Write-Host $line + ' = ' + $retval | Write-Host
} }
} }
@ -50,7 +50,7 @@ function main {
$vmr = Connect-Voicemeeter -Kind $kind $vmr = Connect-Voicemeeter -Kind $kind
if ($interactive) { if ($interactive) {
"Press <Enter> to exit" | Write-Host 'Press <Enter> to exit' | Write-Host
read-hostuntilempty -vmr $vmr read-hostuntilempty -vmr $vmr
return return
} }

View File

@ -13,14 +13,14 @@ param()
Import-Module ..\..\lib\Voicemeeter.psm1 Import-Module ..\..\lib\Voicemeeter.psm1
try { try {
$vmr = Connect-Voicemeeter -Kind "potato" $vmr = Connect-Voicemeeter -Kind 'potato'
$buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6]) $buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6])
"Buses in selection: $($buses)" "Buses in selection: $($buses)"
$unmutedIndex = $null $unmutedIndex = $null
# 1) # 1)
"Cycling through bus selection to check for first unmuted Bus..." | Write-Host 'Cycling through bus selection to check for first unmuted Bus...' | Write-Host
foreach ($bus in $buses) { foreach ($bus in $buses) {
# 2) # 2)
if (-not $bus.mute) { if (-not $bus.mute) {

View File

@ -6,28 +6,28 @@ Import-Module obs-powershell
function CurrentProgramSceneChanged { function CurrentProgramSceneChanged {
param([System.Object]$data) param([System.Object]$data)
Write-Host "Switched to scene", $data.sceneName Write-Host 'Switched to scene', $data.sceneName
switch ($data.sceneName) { switch ($data.sceneName) {
"START" { 'START' {
$vmr.strip[0].mute = !$vmr.strip[0].mute $vmr.strip[0].mute = !$vmr.strip[0].mute
} }
"BRB" { 'BRB' {
$vmr.strip[0].gain = -8.3 $vmr.strip[0].gain = -8.3
} }
"END" { 'END' {
$vmr.strip[0].mono = $true $vmr.strip[0].mono = $true
} }
"LIVE" { 'LIVE' {
$vmr.strip[0].color_x = 0.3 $vmr.strip[0].color_x = 0.3
} }
default { "Expected START, BRB, END or LIVE scene" | Write-Warning; return } default { 'Expected START, BRB, END or LIVE scene' | Write-Warning; return }
} }
} }
function ExitStarted { function ExitStarted {
param([System.Object]$data) param([System.Object]$data)
"OBS shutdown has begun!" | Write-Host 'OBS shutdown has begun!' | Write-Host
break break
} }
@ -38,12 +38,12 @@ function eventHandler($data) {
} }
function ConnFromFile { function ConnFromFile {
$configpath = Join-Path $PSScriptRoot "config.psd1" $configpath = Join-Path $PSScriptRoot 'config.psd1'
return Import-PowerShellDataFile -Path $configpath return Import-PowerShellDataFile -Path $configpath
} }
function main { function main {
$vmr = Connect-Voicemeeter -Kind "basic" $vmr = Connect-Voicemeeter -Kind 'basic'
$conn = ConnFromFile $conn = ConnFromFile
$job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password $job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password

View File

@ -22,7 +22,7 @@ class Remote {
} }
[string] ToString() { [string] ToString() {
return "Voicemeeter " + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1) return 'Voicemeeter ' + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1)
} }
[Remote] Login() { [Remote] Login() {
@ -138,13 +138,13 @@ Function Get-RemotePotato {
Function Connect-Voicemeeter { Function Connect-Voicemeeter {
param([String]$Kind) param([String]$Kind)
switch ($Kind) { switch ($Kind) {
"basic" { 'basic' {
return Get-RemoteBasic return Get-RemoteBasic
} }
"banana" { 'banana' {
return Get-RemoteBanana return Get-RemoteBanana
} }
"potato" { 'potato' {
return Get-RemotePotato return Get-RemotePotato
} }
default { default {

View File

@ -7,16 +7,16 @@ function Login {
) )
$retval = [int][Voicemeeter.Remote]::VBVMR_Login() $retval = [int][Voicemeeter.Remote]::VBVMR_Login()
if ($retval -notin @(0, 1, -2)) { if ($retval -notin @(0, 1, -2)) {
throw [CAPIError]::new($retval, "VBVMR_Login") throw [CAPIError]::new($retval, 'VBVMR_Login')
} }
switch ($retval) { switch ($retval) {
1 { 1 {
"Voicemeeter Engine running but GUI not launched. Launching GUI now." | Write-Verbose 'Voicemeeter Engine running but GUI not launched. Launching GUI now.' | Write-Verbose
RunVoicemeeter -kindId $kindId RunVoicemeeter -kindId $kindId
} }
-2 { -2 {
throw [LoginError]::new("Login may only be called once per session.") throw [LoginError]::new('Login may only be called once per session.')
} }
} }
@ -26,7 +26,7 @@ function Login {
do { do {
Start-Sleep -m 100 Start-Sleep -m 100
try { try {
"Successfully logged into Voicemeeter [" + $(VmType).ToUpper() + "] Version " + $(VmVersion) | Write-Verbose 'Successfully logged into Voicemeeter [' + $(VmType).ToUpper() + '] Version ' + $(VmVersion) | Write-Verbose
$exception = $null $exception = $null
break break
} }
@ -37,7 +37,7 @@ function Login {
} while ($sw.elapsed -lt $timeout) } while ($sw.elapsed -lt $timeout)
if ($null -ne $exception) { if ($null -ne $exception) {
throw [VMRemoteError]::new("Timeout logging into the API.") throw [VMRemoteError]::new('Timeout logging into the API.')
} }
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 } while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
@ -47,9 +47,9 @@ function Logout {
Start-Sleep -m 100 Start-Sleep -m 100
$retval = [int][Voicemeeter.Remote]::VBVMR_Logout() $retval = [int][Voicemeeter.Remote]::VBVMR_Logout()
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_Logout") throw [CAPIError]::new($retval, 'VBVMR_Logout')
} }
if ($retval -eq 0) { "Sucessfully logged out" | Write-Verbose } if ($retval -eq 0) { 'Sucessfully logged out' | Write-Verbose }
} }
function RunVoicemeeter { function RunVoicemeeter {
@ -57,21 +57,21 @@ function RunVoicemeeter {
[string]$kindId [string]$kindId
) )
$kinds = @{ $kinds = @{
"basic" = $(if ([Environment]::Is64BitOperatingSystem) { 4 } else { 1 }) 'basic' = $(if ([Environment]::Is64BitOperatingSystem) { 4 } else { 1 })
"banana" = $(if ([Environment]::Is64BitOperatingSystem) { 5 } else { 2 }) 'banana' = $(if ([Environment]::Is64BitOperatingSystem) { 5 } else { 2 })
"potato" = $(if ([Environment]::Is64BitOperatingSystem) { 6 } else { 3 }) 'potato' = $(if ([Environment]::Is64BitOperatingSystem) { 6 } else { 3 })
} }
$retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$kinds[$kindId]) $retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$kinds[$kindId])
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_RunVoicemeeter") throw [CAPIError]::new($retval, 'VBVMR_RunVoicemeeter')
} }
} }
function P_Dirty { function P_Dirty {
$retval = [Voicemeeter.Remote]::VBVMR_IsParametersDirty() $retval = [Voicemeeter.Remote]::VBVMR_IsParametersDirty()
if ($retval -notin @(0, 1)) { if ($retval -notin @(0, 1)) {
throw [CAPIError]::new($retval, "VBVMR_IsParametersDirty") throw [CAPIError]::new($retval, 'VBVMR_IsParametersDirty')
} }
[bool]$retval [bool]$retval
} }
@ -79,7 +79,7 @@ function P_Dirty {
function M_Dirty { function M_Dirty {
$retval = [Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty() $retval = [Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty()
if ($retval -notin @(0, 1)) { if ($retval -notin @(0, 1)) {
throw [CAPIError]::new($retval, "VBVMR_MacroButton_IsDirty") throw [CAPIError]::new($retval, 'VBVMR_MacroButton_IsDirty')
} }
[bool]$retval [bool]$retval
} }
@ -88,12 +88,12 @@ function VmType {
New-Variable -Name ptr -Value 0 New-Variable -Name ptr -Value 0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterType([ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterType([ref]$ptr)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterType") throw [CAPIError]::new($retval, 'VBVMR_GetVoicemeeterType')
} }
switch ($ptr) { switch ($ptr) {
1 { return "basic" } 1 { return 'basic' }
2 { return "banana" } 2 { return 'banana' }
3 { return "potato" } 3 { return 'potato' }
} }
} }
@ -101,7 +101,7 @@ function VmVersion {
New-Variable -Name ptr -Value 0 New-Variable -Name ptr -Value 0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterVersion([ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterVersion([ref]$ptr)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterVersion") throw [CAPIError]::new($retval, 'VBVMR_GetVoicemeeterVersion')
} }
$v1 = ($ptr -band 0xFF000000) -shr 24 $v1 = ($ptr -band 0xFF000000) -shr 24
$v2 = ($ptr -band 0x00FF0000) -shr 16 $v2 = ($ptr -band 0x00FF0000) -shr 16
@ -122,7 +122,7 @@ function Param_Get {
$BYTES = [System.Byte[]]::new(512) $BYTES = [System.Byte[]]::new(512)
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES) $retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_GetParameterStringA") throw [CAPIError]::new($retval, 'VBVMR_GetParameterStringA')
} }
[System.Text.Encoding]::ASCII.GetString($BYTES).Trim([char]0) [System.Text.Encoding]::ASCII.GetString($BYTES).Trim([char]0)
} }
@ -130,7 +130,7 @@ function Param_Get {
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_GetParameterFloat") throw [CAPIError]::new($retval, 'VBVMR_GetParameterFloat')
} }
[single]$ptr [single]$ptr
} }
@ -143,13 +143,13 @@ function Param_Set {
if ($VALUE -is [string]) { if ($VALUE -is [string]) {
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_SetParameterStringA") throw [CAPIError]::new($retval, 'VBVMR_SetParameterStringA')
} }
} }
else { else {
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_SetParameterFloat") throw [CAPIError]::new($retval, 'VBVMR_SetParameterFloat')
} }
} }
} }
@ -160,7 +160,7 @@ function MB_Set {
) )
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE) $retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_MacroButton_SetStatus") throw [CAPIError]::new($retval, 'VBVMR_MacroButton_SetStatus')
} }
} }
@ -174,7 +174,7 @@ function MB_Get {
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE) $retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_MacroButton_GetStatus") throw [CAPIError]::new($retval, 'VBVMR_MacroButton_GetStatus')
} }
[int]$ptr [int]$ptr
} }
@ -184,8 +184,8 @@ function Param_Set_Multi {
[hashtable]$HASH [hashtable]$HASH
) )
foreach ($key in $HASH.keys) { foreach ($key in $HASH.keys) {
$classobj, $m2, $m3 = $key.Split("_") $classobj, $m2, $m3 = $key.Split('_')
if ($m2 -match "^\d+$") { $index = [int]$m2 } else { $index = [int]$m3 } if ($m2 -match '^\d+$') { $index = [int]$m2 } else { $index = [int]$m3 }
foreach ($h in $HASH[$key].GetEnumerator()) { foreach ($h in $HASH[$key].GetEnumerator()) {
$property = $h.Name $property = $h.Name
@ -207,11 +207,11 @@ function Set_By_Script {
[string]$script [string]$script
) )
if ($script.Length -gt 48000) { if ($script.Length -gt 48000) {
throw [VMRemoteError]::new("Script size cannot be larger than 48kB") throw [VMRemoteError]::new('Script size cannot be larger than 48kB')
} }
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_SetParameters") throw [CAPIError]::new($retval, 'VBVMR_SetParameters')
} }
} }
@ -222,7 +222,7 @@ function Get_Level {
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr)
if ($retval -notin @(0)) { if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_GetLevel") throw [CAPIError]::new($retval, 'VBVMR_GetLevel')
} }
[float]$ptr [float]$ptr
} }

View File

@ -3,9 +3,9 @@
function Setup_DLL { function Setup_DLL {
$VMPATH = Get_VMPath $VMPATH = Get_VMPath
$dll = Join-Path -Path $VMPATH -ChildPath ("VoicemeeterRemote" + ` $dll = Join-Path -Path $VMPATH -ChildPath ('VoicemeeterRemote' + `
(& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + ` (& { if ([Environment]::Is64BitOperatingSystem) { '64' } else { '' } }) + `
".dll") '.dll')
$Signature = @" $Signature = @"
[DllImport(@"$dll")] [DllImport(@"$dll")]

View File

@ -8,7 +8,7 @@ class IBus {
} }
[string] identifier () { [string] identifier () {
return "Bus[" + $this.index + "]" return 'Bus[' + $this.index + ']'
} }
[single] Getter ($param) { [single] Getter ($param) {
@ -106,7 +106,7 @@ class BusMode : IBus {
} }
[string] identifier () { [string] identifier () {
return "Bus[" + $this.index + "].mode" return 'Bus[' + $this.index + '].mode'
} }
[string] Get () { [string] Get () {
@ -125,7 +125,7 @@ class BusEq : IBus {
} }
[string] identifier () { [string] identifier () {
return "Bus[" + $this.index + "].EQ" return 'Bus[' + $this.index + '].EQ'
} }
} }
@ -142,7 +142,7 @@ class BusDevice : IBus {
} }
[string] identifier () { [string] identifier () {
return "Bus[" + $this.index + "].Device" return 'Bus[' + $this.index + '].Device'
} }
hidden $_name = $($this | Add-Member ScriptProperty 'name' ` hidden $_name = $($this | Add-Member ScriptProperty 'name' `

View File

@ -8,7 +8,7 @@ class Special {
} }
[string] identifier () { [string] identifier () {
return "Command" return 'Command'
} }
[string] ToString() { [string] ToString() {
@ -29,13 +29,13 @@ class Special {
} }
[void] RunMacrobuttons() { [void] RunMacrobuttons() {
"Launching the MacroButtons app" | Write-Verbose 'Launching the MacroButtons app' | Write-Verbose
Start-Process -FilePath $(Join-Path -Path $this.remote.vmpath -ChildPath "VoicemeeterMacroButtons.exe") Start-Process -FilePath $(Join-Path -Path $this.remote.vmpath -ChildPath 'VoicemeeterMacroButtons.exe')
} }
[void] CloseMacrobuttons() { [void] CloseMacrobuttons() {
"Closing the MacroButtons app" | Write-Verbose 'Closing the MacroButtons app' | Write-Verbose
Stop-Process -Name "VoicemeeterMacroButtons" Stop-Process -Name 'VoicemeeterMacroButtons'
} }
hidden $_hide = $($this | Add-Member ScriptProperty 'hide' ` hidden $_hide = $($this | Add-Member ScriptProperty 'hide' `

View File

@ -1,19 +1,19 @@
function Get_VMPath { function Get_VMPath {
$REG_KEY = @( $REG_KEY = @(
"Registry::HKEY_LOCAL_MACHINE", 'Registry::HKEY_LOCAL_MACHINE',
"Software", 'Software',
(& { if ([Environment]::Is64BitOperatingSystem) { "WOW6432Node" } else { "" } }), (& { if ([Environment]::Is64BitOperatingSystem) { 'WOW6432Node' } else { '' } }),
"Microsoft", 'Microsoft',
"Windows", 'Windows',
"CurrentVersion", 'CurrentVersion',
"Uninstall" 'Uninstall'
).Where({ $_ -ne "" }) -Join "\" ).Where({ $_ -ne '' }) -Join '\'
$VM_KEY = "VB:Voicemeeter {17359A74-1236-5467}" $VM_KEY = 'VB:Voicemeeter {17359A74-1236-5467}'
try { try {
return $(Get-ItemPropertyValue -Path (@($REG_KEY, $VM_KEY) -Join "\") -Name UninstallString | Split-Path -Parent) return $(Get-ItemPropertyValue -Path (@($REG_KEY, $VM_KEY) -Join '\') -Name UninstallString | Split-Path -Parent)
} }
catch { catch {
throw [VMRemoteError]::new("Unable to fetch Voicemeeter path from the Registry.") throw [VMRemoteError]::new('Unable to fetch Voicemeeter path from the Registry.')
} }
} }

View File

@ -1,30 +1,30 @@
$KindMap = @{ $KindMap = @{
"basic" = @{ 'basic' = @{
"name" = "basic" 'name' = 'basic'
"p_in" = 2 'p_in' = 2
"v_in" = 1 'v_in' = 1
"p_out" = 1 'p_out' = 1
"v_out" = 1 'v_out' = 1
"vban_in" = 4 'vban_in' = 4
"vban_out" = 4 'vban_out' = 4
}; };
"banana" = @{ 'banana' = @{
"name" = "banana" 'name' = 'banana'
"p_in" = 3 'p_in' = 3
"v_in" = 2 'v_in' = 2
"p_out" = 3 'p_out' = 3
"v_out" = 2 'v_out' = 2
"vban_in" = 8 'vban_in' = 8
"vban_out" = 8 'vban_out' = 8
}; };
"potato" = @{ 'potato' = @{
"name" = "potato" 'name' = 'potato'
"p_in" = 5 'p_in' = 5
"v_in" = 3 'v_in' = 3
"p_out" = 5 'p_out' = 5
"v_out" = 3 'v_out' = 3
"vban_in" = 8 'vban_in' = 8
"vban_out" = 8 'vban_out' = 8
}; };
} }

View File

@ -5,9 +5,9 @@ function AddBoolMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[bool]`$this.Getter('{0}')" -f $param $Signatures['Getter'] = "[bool]`$this.Getter('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" ` $Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@ -21,9 +21,9 @@ function AddFloatMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[math]::Round(`$this.Getter('{0}'), 1)" -f $param $Signatures['Getter'] = "[math]::Round(`$this.Getter('{0}'), 1)" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" ` $Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@ -37,9 +37,9 @@ function AddIntMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[Int]`$this.Getter('{0}')" -f $param $Signatures['Getter'] = "[Int]`$this.Getter('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" ` $Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@ -53,9 +53,9 @@ function AddStringMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[String]`$this.Getter_String('{0}')" -f $param $Signatures['Getter'] = "[String]`$this.Getter_String('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" ` $Signatures['Setter'] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@ -69,9 +69,9 @@ function AddActionMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "`$this.Setter('{0}', `$true)" -f $param $Signatures['Getter'] = "`$this.Setter('{0}', `$true)" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "" $Signatures['Setter'] = ''
Addmember Addmember
} }
@ -83,7 +83,7 @@ function AddChannelMembers () {
[System.Collections.ArrayList]$channels = @() [System.Collections.ArrayList]$channels = @()
1..$($num_A + $num_B) | ForEach-Object { 1..$($num_A + $num_B) | ForEach-Object {
if ($_ -le $num_A) { $channels.Add("A{0}" -f $_) } else { $channels.Add("B{0}" -f $($_ - $num_A)) } if ($_ -le $num_A) { $channels.Add('A{0}' -f $_) } else { $channels.Add('B{0}' -f $($_ - $num_A)) }
} }
AddBoolMembers -PARAMS $channels AddBoolMembers -PARAMS $channels
@ -93,11 +93,11 @@ function AddGainlayerMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
0..7 | ForEach-Object { 0..7 | ForEach-Object {
# Define getter # Define getter
$Signatures["Getter"] = "`$this.Getter('gainlayer[{0}]')" -f $_ $Signatures['Getter'] = "`$this.Getter('gainlayer[{0}]')" -f $_
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('gainlayer[{0}]', `$arg)" ` $Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('gainlayer[{0}]', `$arg)" `
-f $_ -f $_
$param = "gainlayer{0}" -f $_ $param = 'gainlayer{0}' -f $_
$null = $param $null = $param
Addmember Addmember
@ -108,8 +108,8 @@ function Addmember {
$AddMemberParams = @{ $AddMemberParams = @{
Name = $param Name = $param
MemberType = 'ScriptProperty' MemberType = 'ScriptProperty'
Value = [scriptblock]::Create($Signatures["Getter"]) Value = [scriptblock]::Create($Signatures['Getter'])
SecondValue = [scriptblock]::Create($Signatures["Setter"]) SecondValue = [scriptblock]::Create($Signatures['Setter'])
} }
$this | Add-Member @AddMemberParams $this | Add-Member @AddMemberParams
} }

View File

@ -1,5 +1,5 @@
function Get_Profiles ([string]$kind_id) { function Get_Profiles ([string]$kind_id) {
$basepath = Join-Path -Path $(Split-Path -Path $PSScriptRoot) -ChildPath "profiles" $basepath = Join-Path -Path $(Split-Path -Path $PSScriptRoot) -ChildPath 'profiles'
if (Test-Path $basepath) { if (Test-Path $basepath) {
$fullpath = Join-Path -Path $basepath -ChildPath $kind_id $fullpath = Join-Path -Path $basepath -ChildPath $kind_id
} }
@ -11,7 +11,7 @@ function Get_Profiles ([string]$kind_id) {
$filenames | ForEach-Object { $filenames | ForEach-Object {
(Join-Path -Path $fullpath -ChildPath $_) | ForEach-Object { (Join-Path -Path $fullpath -ChildPath $_) | ForEach-Object {
$filename = [System.IO.Path]::GetFileNameWithoutExtension($_) $filename = [System.IO.Path]::GetFileNameWithoutExtension($_)
Write-Host ("Importing profile " + $kind_id + "/" + $filename) Write-Host ('Importing profile ' + $kind_id + '/' + $filename)
$data[$filename] = Import-PowerShellDataFile -Path $_ $data[$filename] = Import-PowerShellDataFile -Path $_
} }
} }

View File

@ -51,7 +51,7 @@ class Recorder : IRecorder {
} }
[string] identifier () { [string] identifier () {
return "Recorder" return 'Recorder'
} }
[string] ToString() { [string] ToString() {
@ -137,9 +137,9 @@ class Recorder : IRecorder {
[void] GoTo ([string]$timestring) { [void] GoTo ([string]$timestring) {
try { try {
if ([datetime]::ParseExact($timestring, "HH:mm:ss", $null)) { if ([datetime]::ParseExact($timestring, 'HH:mm:ss', $null)) {
$timespan = [timespan]::Parse($timestring) $timespan = [timespan]::Parse($timestring)
$this.Setter("GoTo", $timespan.TotalSeconds) $this.Setter('GoTo', $timespan.TotalSeconds)
} }
} }
catch [FormatException] { catch [FormatException] {
@ -150,13 +150,13 @@ class Recorder : IRecorder {
[void] FileType($format) { [void] FileType($format) {
[int]$val = 0 [int]$val = 0
switch ($format) { switch ($format) {
"wav" { $val = 1 } 'wav' { $val = 1 }
"aiff" { $val = 2 } 'aiff' { $val = 2 }
"bwf" { $val = 3 } 'bwf' { $val = 3 }
"mp3" { $val = 100 } 'mp3' { $val = 100 }
default { "Filetype() got: $format, expected one of 'wav', 'aiff', 'bwf', 'mp3'" } default { "Filetype() got: $format, expected one of 'wav', 'aiff', 'bwf', 'mp3'" }
} }
$this.Setter("filetype", $val) $this.Setter('filetype', $val)
} }
} }
@ -166,7 +166,7 @@ class RecorderMode : IRecorder {
} }
[string] identifier () { [string] identifier () {
return "Recorder.Mode" return 'Recorder.Mode'
} }
} }
@ -178,7 +178,7 @@ class RecorderArm : IRecorder {
} }
Set ([bool]$val) { Set ([bool]$val) {
$this.Setter("", $(if ($val) { 1 } else { 0 })) $this.Setter('', $(if ($val) { 1 } else { 0 }))
} }
} }

View File

@ -8,7 +8,7 @@ class IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "]" return 'Strip[' + $this.index + ']'
} }
[single] Getter ($param) { [single] Getter ($param) {
@ -135,7 +135,7 @@ class StripComp : IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].Comp" return 'Strip[' + $this.index + '].Comp'
} }
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
@ -155,7 +155,7 @@ class StripGate : IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].Gate" return 'Strip[' + $this.index + '].Gate'
} }
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
@ -174,7 +174,7 @@ class StripDenoiser : IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].Denoiser" return 'Strip[' + $this.index + '].Denoiser'
} }
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
@ -194,7 +194,7 @@ class StripEq : IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].EQ" return 'Strip[' + $this.index + '].EQ'
} }
} }
@ -203,7 +203,7 @@ class StripDevice : IStrip {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].Device" return 'Strip[' + $this.index + '].Device'
} }
hidden $_name = $($this | Add-Member ScriptProperty 'name' ` hidden $_name = $($this | Add-Member ScriptProperty 'name' `

View File

@ -10,7 +10,7 @@ class IVban {
} }
[string] identifier () { [string] identifier () {
return "vban." + $this.direction + "stream[" + $this.index + "]" return 'vban.' + $this.direction + 'stream[' + $this.index + ']'
} }
[single] Getter ($param) { [single] Getter ($param) {
@ -94,7 +94,7 @@ class Vban : IVban {
} ` } `
{ {
param([int]$arg) param([int]$arg)
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') } if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
else { else {
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) $opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
if ($opts.Contains($arg)) { if ($opts.Contains($arg)) {
@ -113,7 +113,7 @@ class Vban : IVban {
} ` } `
{ {
param([int]$arg) param([int]$arg)
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') } if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
else { else {
if ($arg -ge 1 -and $arg -le 8) { if ($arg -ge 1 -and $arg -le 8) {
$this._channel = $this.Setter('channel', $arg) $this._channel = $this.Setter('channel', $arg)
@ -132,7 +132,7 @@ class Vban : IVban {
} ` } `
{ {
param([int]$arg) param([int]$arg)
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') } if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
else { else {
if (@(16, 24).Contains($arg)) { if (@(16, 24).Contains($arg)) {
$val = if ($arg -eq 16) { 1 } else { 2 } $val = if ($arg -eq 16) { 1 } else { 2 }
@ -151,7 +151,7 @@ class Vban : IVban {
} ` } `
{ {
param([int]$arg) param([int]$arg)
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') } if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
else { else {
if ($arg -ge 0 -and $arg -le 4) { if ($arg -ge 0 -and $arg -le 4) {
$this._quality = $this.Setter('quality', $arg) $this._quality = $this.Setter('quality', $arg)
@ -169,7 +169,7 @@ class Vban : IVban {
} ` } `
{ {
param([int]$arg) param([int]$arg)
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') } if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
else { else {
if ($arg -ge 0 -and $arg -le 8) { if ($arg -ge 0 -and $arg -le 8) {
$this._route = $this.Setter('route', $arg) $this._route = $this.Setter('route', $arg)
@ -200,10 +200,10 @@ function Make_Vban ([Object]$remote) {
[System.Collections.ArrayList]$outstream = @() [System.Collections.ArrayList]$outstream = @()
0..$($remote.kind.vban_in - 1) | ForEach-Object { 0..$($remote.kind.vban_in - 1) | ForEach-Object {
[void]$instream.Add([VbanInstream]::new($_, $remote, "in")) [void]$instream.Add([VbanInstream]::new($_, $remote, 'in'))
} }
0..$($remote.kind.vban_out - 1) | ForEach-Object { 0..$($remote.kind.vban_out - 1) | ForEach-Object {
[void]$outstream.Add([VbanOutstream]::new($_, $remote, "out")) [void]$outstream.Add([VbanOutstream]::new($_, $remote, 'out'))
} }
$CustomObject = [pscustomobject]@{ $CustomObject = [pscustomobject]@{
@ -213,7 +213,7 @@ function Make_Vban ([Object]$remote) {
$CustomObject | Add-Member ScriptProperty 'enable' ` $CustomObject | Add-Member ScriptProperty 'enable' `
{ {
return Write-Warning ("ERROR: vban.enable is write only") return Write-Warning ('ERROR: vban.enable is write only')
} ` } `
{ {
param([bool]$arg) param([bool]$arg)

View File

@ -90,17 +90,17 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
} }
Context 'Recorder' -Skip:$ifBasic { Context 'Recorder' -Skip:$ifBasic {
It "Should set and get Recorder.A3" { It 'Should set and get Recorder.A3' {
$vmr.recorder.A3 = $value $vmr.recorder.A3 = $value
$vmr.recorder.A3 | Should -Be $expected $vmr.recorder.A3 | Should -Be $expected
} }
It "Should set and get Recorder.B1" { It 'Should set and get Recorder.B1' {
$vmr.recorder.B1 = $value $vmr.recorder.B1 = $value
$vmr.recorder.B1 | Should -Be $expected $vmr.recorder.B1 | Should -Be $expected
} }
It "Should set and get Recorder.loop" { It 'Should set and get Recorder.loop' {
$vmr.recorder.loop = $value $vmr.recorder.loop = $value
} }
} }
@ -248,8 +248,8 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
@{ Index = $phys_in }, @{ Index = $virt_in } @{ Index = $phys_in }, @{ Index = $virt_in }
) { ) {
It "Should set Strip[$index].Label" -ForEach @( It "Should set Strip[$index].Label" -ForEach @(
@{ Value = "test0"; Expected = "test0" } @{ Value = 'test0'; Expected = 'test0' }
@{ Value = "test1"; Expected = "test1" } @{ Value = 'test1'; Expected = 'test1' }
) { ) {
$vmr.strip[$index].label = $value $vmr.strip[$index].label = $value
$vmr.strip[$index].label | Should -Be $expected $vmr.strip[$index].label | Should -Be $expected
@ -260,8 +260,8 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
@{ Index = $phys_out }, @{ Index = $virt_out } @{ Index = $phys_out }, @{ Index = $virt_out }
) { ) {
It "Should set Bus[$index].Label" -ForEach @( It "Should set Bus[$index].Label" -ForEach @(
@{ Value = "test0"; Expected = "test0" } @{ Value = 'test0'; Expected = 'test0' }
@{ Value = "test1"; Expected = "test1" } @{ Value = 'test1'; Expected = 'test1' }
) { ) {
$vmr.bus[$index].label = $value $vmr.bus[$index].label = $value
$vmr.bus[$index].label | Should -Be $expected $vmr.bus[$index].label | Should -Be $expected
@ -273,7 +273,7 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
) { ) {
Context 'instream' { Context 'instream' {
Context 'ip' -ForEach @( Context 'ip' -ForEach @(
@{ Value = "0.0.0.0"; Expected = "0.0.0.0" } @{ Value = '0.0.0.0'; Expected = '0.0.0.0' }
) { ) {
It "Should set vban.instream[$index].name to $value" { It "Should set vban.instream[$index].name to $value" {
$vmr.vban.instream[$index].ip = $value $vmr.vban.instream[$index].ip = $value
@ -284,7 +284,7 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
Context 'outstream' { Context 'outstream' {
Context 'ip' -ForEach @( Context 'ip' -ForEach @(
@{ Value = "0.0.0.0"; Expected = "0.0.0.0" } @{ Value = '0.0.0.0'; Expected = '0.0.0.0' }
) { ) {
It "Should set vban.outstream[$index].name to $value" { It "Should set vban.outstream[$index].name to $value" {
$vmr.vban.outstream[$index].ip = $value $vmr.vban.outstream[$index].ip = $value

View File

@ -29,7 +29,7 @@ Describe -Tag 'lower', -TestName 'All Lower Tests' {
@{ Index = $phys_in }, @{ Index = $virt_in } @{ Index = $phys_in }, @{ Index = $virt_in }
) { ) {
Context 'mute, mono, A1, B2' -ForEach @( Context 'mute, mono, A1, B2' -ForEach @(
@{ param = "mute" }, @{ param = "A1" } @{ param = 'mute' }, @{ param = 'A1' }
) { ) {
It "Should set Strip[0].$param to 1" { It "Should set Strip[0].$param to 1" {
Param_Set -PARAM "Strip[$index].$param" -VALUE $value Param_Set -PARAM "Strip[$index].$param" -VALUE $value

View File

@ -1,76 +0,0 @@
Param([String]$tag, [Int]$num = 1, [switch]$log, [string]$kind = "potato")
Import-Module .\lib\Voicemeeter.psm1
Function ParseLog {
Param([String]$logfile)
$summary_file = Join-Path $PSScriptRoot "_summary.log"
if (Test-Path $summary_file) { Clear-Content $summary_file }
$PASSED_PATTERN = "^PassedCount\s+:\s(\d+)"
$FAILED_PATTERN = "^FailedCount\s+:\s(\d+)"
$DATA = @{
"passed" = 0
"failed" = 0
}
ForEach ($line in `
$(Get-Content -Path "${logfile}")) {
if ($line -match $PASSED_PATTERN) {
$DATA["passed"] += $Matches[1]
}
elseif ($line -match $FAILED_PATTERN) {
$DATA["failed"] += $Matches[1]
}
}
"=========================`n" + `
"$num tests run:`n" + `
"=========================" | Tee-Object -FilePath $summary_file -Append
$DATA | ForEach-Object { $_ } | Tee-Object -FilePath $summary_file -Append
}
function main() {
try {
$vmr = Connect-Voicemeeter -Kind $kind
$vmr.command.RunMacrobuttons() # ensure macrobuttons is running before we begin
Write-Host "Running tests for $vmr"
# test boundaries by kind
$phys_in = $vmr.kind.p_in - 1
$virt_in = $vmr.kind.p_in + $vmr.kind.v_in - 1
$phys_out = $vmr.kind.p_out - 1
$virt_out = $vmr.kind.p_out + $vmr.kind.v_out - 1
$vban_in = $vmr.kind.vban_in - 1
$vban_out = $vmr.kind.vban_out - 1
# skip conditions by kind
$ifBasic = $vmr.kind.name -eq "basic"
$ifBanana = $vmr.kind.name -eq "banana"
$ifPotato = $vmr.kind.name -eq "potato"
$ifNotBasic = $vmr.kind.name -ne "basic"
$ifNotBanana = $vmr.kind.name -ne "banana"
$ifNotPotato = $vmr.kind.name -ne "potato"
$logfile = Join-Path $PSScriptRoot "_results.log"
if (Test-Path $logfile) { Clear-Content $logfile }
1..$num | ForEach-Object {
if ($log) {
"Running test $_ of $num" | Tee-Object -FilePath $logfile -Append
Invoke-Pester -Tag $tag -PassThru | Tee-Object -FilePath $logfile -Append
}
else {
"Running test $_ of $num"
Invoke-Pester -Tag $tag -PassThru
}
}
if ($log) { Parselog -logfile $logfile }
}
finally { Disconnect-Voicemeeter }
}
main

30
tests/run.ps1 Normal file
View File

@ -0,0 +1,30 @@
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Target = "variablename")]
Param([String]$tag, [string]$kind = 'potato')
Import-Module .\lib\Voicemeeter.psm1
function main() {
try {
$vmr = Connect-Voicemeeter -Kind $kind
$vmr.command.RunMacrobuttons() # ensure macrobuttons is running before we begin
Write-Host "Running tests for $vmr"
# test boundaries by kind
$phys_in = $vmr.kind.p_in - 1
$virt_in = $vmr.kind.p_in + $vmr.kind.v_in - 1
$phys_out = $vmr.kind.p_out - 1
$virt_out = $vmr.kind.p_out + $vmr.kind.v_out - 1
$vban_in = $vmr.kind.vban_in - 1
$vban_out = $vmr.kind.vban_out - 1
# skip conditions by kind
$ifBasic = $vmr.kind.name -eq 'basic'
$ifNotPotato = $vmr.kind.name -ne 'potato'
Invoke-Pester -Tag $tag -PassThru | Out-Null
}
finally { Disconnect-Voicemeeter }
}
main