Compare commits

..

No commits in common. "bd0779add2d6acf87b1eb3aff1f8d3770fb71b12" and "f199fa587f75cd31d7c087fb755764f7b0a5d094" have entirely different histories.

23 changed files with 285 additions and 237 deletions

5
.gitignore vendored
View File

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

14
.vscode/launch.json vendored
View File

@ -51,9 +51,21 @@
"type": "PowerShell", "type": "PowerShell",
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"script": "${workspaceFolder}/tests/run.ps1", "script": "${workspaceFolder}/tests/pre-commit.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
Parameters: Run tests using .\tests\pre-commit.ps1 which accepts the following 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
*with Task* Run tests from repository root in a subshell and write logs, like so:
```console `powershell .\tests\pre-commit.ps1 -k "potato" -t "higher" -log`
task test -- -t "higher" -k "banana"
```
### Official Documentation ### Official Documentation

View File

@ -1,11 +0,0 @@
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

76
tests/pre-commit.ps1 Normal file
View File

@ -0,0 +1,76 @@
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

View File

@ -1,30 +0,0 @@
[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