From c086f58ade7faf12749d450850ec66b6b7b87d77 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Tue, 25 Nov 2025 18:54:36 -0500 Subject: [PATCH 1/7] ArrayMember classes --- CHANGELOG.md | 1 + lib/Voicemeeter.psm1 | 1 + lib/arraymember.ps1 | 64 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 lib/arraymember.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cfe68d..d5b9cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Before any major/minor/patch is released all test units will be run to verify th ### Added - IRemote base class +- ArrayMember classes for array-like properties ## [3.3.0] - 2024-06-29 diff --git a/lib/Voicemeeter.psm1 b/lib/Voicemeeter.psm1 index 7002acb..272ab53 100644 --- a/lib/Voicemeeter.psm1 +++ b/lib/Voicemeeter.psm1 @@ -3,6 +3,7 @@ . $PSScriptRoot\base.ps1 . $PSScriptRoot\kinds.ps1 . $PSScriptRoot\iremote.ps1 +. $PSScriptRoot\arraymember.ps1 . $PSScriptRoot\strip.ps1 . $PSScriptRoot\bus.ps1 . $PSScriptRoot\macrobuttons.ps1 diff --git a/lib/arraymember.ps1 b/lib/arraymember.ps1 new file mode 100644 index 0000000..0a81cb2 --- /dev/null +++ b/lib/arraymember.ps1 @@ -0,0 +1,64 @@ +class ArrayMember : IRemote { + [string]$prefix + [Object]$parent + + ArrayMember ( + [int]$index, [string]$prefix, [Object]$parent + ) : base ($index, $parent.remote) { + $this.prefix = $prefix + $this.parent = $parent + } + + [string] identifier () { + $parentId = $this.parent.identifier() + return "{0}.{1}[{2}]" -f $parentId, $this.prefix, $this.index + } + + [void] Set ($val) { + $this.Setter('', $val) + } +} + +class BoolArrayMember : ArrayMember { + BoolArrayMember ( + [int]$index, [string]$prefix, [Object]$parent + ) : base ($index, $prefix, $parent) {} + + [bool] Get () { + return [bool]$this.Getter('') + } +} + +class IntArrayMember : ArrayMember { + IntArrayMember ( + [int]$index, [string]$prefix, [Object]$parent + ) : base ($index, $prefix, $parent) {} + + [int] Get () { + return [int]$this.Getter('') + } +} + +class FloatArrayMember : ArrayMember { + [int]$decimals + + FloatArrayMember ( + [int]$index, [string]$prefix, [Object]$parent, [int]$decimals = 1 + ) : base ($index, $prefix, $parent) { + $this.decimals = $decimals + } + + [double] Get () { + return [math]::Round($this.Getter(''), $this.decimals) + } +} + +class StringArrayMember : ArrayMember { + StringArrayMember ( + [int]$index, [string]$prefix, [Object]$parent + ) : base ($index, $prefix, $parent) {} + + [string] Get () { + return [string]$this.Getter_String('') + } +} \ No newline at end of file From 3a5c7286f6d362de921c233acdc85bc80c97d1c7 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Tue, 25 Nov 2025 20:38:57 -0500 Subject: [PATCH 2/7] Patch Patch class with: - Patch.asio[i] - Patch.OutA2[i]-OutA5[i] - Patch.composite[i] - Patch.insert[i] - Patch.postFaderComposite - Patch.postFxInsert --- lib/Voicemeeter.psm1 | 7 +++++++ lib/patch.ps1 | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 lib/patch.ps1 diff --git a/lib/Voicemeeter.psm1 b/lib/Voicemeeter.psm1 index 272ab53..05fad2e 100644 --- a/lib/Voicemeeter.psm1 +++ b/lib/Voicemeeter.psm1 @@ -10,6 +10,7 @@ . $PSScriptRoot\vban.ps1 . $PSScriptRoot\command.ps1 . $PSScriptRoot\recorder.ps1 +. $PSScriptRoot\patch.ps1 . $PSScriptRoot\profiles.ps1 class Remote { @@ -79,6 +80,7 @@ class RemoteBasic : Remote { [System.Collections.ArrayList]$button [PSCustomObject]$vban [Object]$command + [Object]$patch RemoteBasic () : base ('basic') { $this.strip = Make_Strips($this) @@ -86,6 +88,7 @@ class RemoteBasic : Remote { $this.button = Make_Buttons $this.vban = Make_Vban($this) $this.command = Make_Command($this) + $this.patch = Make_Patch($this) } } @@ -95,6 +98,7 @@ class RemoteBanana : Remote { [System.Collections.ArrayList]$button [PSCustomObject]$vban [Object]$command + [Object]$patch [Object]$recorder RemoteBanana () : base ('banana') { @@ -103,6 +107,7 @@ class RemoteBanana : Remote { $this.button = Make_Buttons $this.vban = Make_Vban($this) $this.command = Make_Command($this) + $this.patch = Make_Patch($this) $this.recorder = Make_Recorder($this) } } @@ -113,6 +118,7 @@ class RemotePotato : Remote { [System.Collections.ArrayList]$button [PSCustomObject]$vban [Object]$command + [Object]$patch [Object]$recorder RemotePotato () : base ('potato') { @@ -121,6 +127,7 @@ class RemotePotato : Remote { $this.button = Make_Buttons $this.vban = Make_Vban($this) $this.command = Make_Command($this) + $this.patch = Make_Patch($this) $this.recorder = Make_Recorder($this) } } diff --git a/lib/patch.ps1 b/lib/patch.ps1 new file mode 100644 index 0000000..e0a512a --- /dev/null +++ b/lib/patch.ps1 @@ -0,0 +1,49 @@ +class Patch : IRemote { + [System.Collections.ArrayList]$asio + [System.Collections.ArrayList]$composite + [System.Collections.ArrayList]$insert + + Patch ([Object]$remote) : base ($remote) { + AddBoolMembers -PARAMS @('postFaderComposite', 'postFxInsert') + + $this.AddASIOOutMembers() + + $this.asio = @() + for ($i = 0; $i -lt $remote.kind.asio_in; $i++) { + $this.asio.Add([IntArrayMember]::new($i, 'asio', $this)) + } + + $this.composite = @() + for ($i = 0; $i -lt $remote.kind.composite; $i++) { + $this.composite.Add([IntArrayMember]::new($i, 'composite', $this)) + } + + $this.insert = @() + for ($i = 0; $i -lt $remote.kind.insert; $i++) { + $this.insert.Add([BoolArrayMember]::new($i, 'insert', $this)) + } + } + + [string] identifier () { + return 'Patch' + } + + hidden [void] AddASIOOutMembers () { + $num_A = $this.remote.kind.p_out + $asio_out = $this.remote.kind.asio_out + + if ($asio_out -le 0) { return } + + for ($a = 2; $a -le $num_A; $a++) { + [System.Collections.ArrayList]$members = @() + for ($i = 0; $i -lt $asio_out; $i++) { + $members.Add([IntArrayMember]::new($i, "OutA$a", $this)) + } + Add-Member -InputObject $this -MemberType NoteProperty -Name "OutA$a" -Value $members -Force + } + } +} + +function Make_Patch ([Object]$remote) { + return [Patch]::new($remote) +} \ No newline at end of file From e0b01288ff18d52876c16efe820f79cd4c6a6bf9 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Tue, 25 Nov 2025 20:43:31 -0500 Subject: [PATCH 3/7] Update kinds.ps1 --- lib/kinds.ps1 | 56 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/kinds.ps1 b/lib/kinds.ps1 index 13ce574..7591f1a 100644 --- a/lib/kinds.ps1 +++ b/lib/kinds.ps1 @@ -1,33 +1,45 @@ $KindMap = @{ 'basic' = @{ - 'name' = 'basic' - 'p_in' = 2 - 'v_in' = 1 - 'p_out' = 1 - 'v_out' = 1 - 'vban_in' = 4 - 'vban_out' = 4 + 'name' = 'basic' + 'p_in' = 2 + 'v_in' = 1 + 'p_out' = 1 + 'v_out' = 1 + 'asio_in' = 4 + 'asio_out' = 0 + 'composite' = 0 + 'insert' = 0 + 'vban_in' = 4 + 'vban_out' = 4 }; 'banana' = @{ - 'name' = 'banana' - 'p_in' = 3 - 'v_in' = 2 - 'p_out' = 3 - 'v_out' = 2 - 'vban_in' = 8 - 'vban_out' = 8 + 'name' = 'banana' + 'p_in' = 3 + 'v_in' = 2 + 'p_out' = 3 + 'v_out' = 2 + 'asio_in' = 6 + 'asio_out' = 8 + 'composite' = 8 + 'insert' = 22 + 'vban_in' = 8 + 'vban_out' = 8 }; 'potato' = @{ - 'name' = 'potato' - 'p_in' = 5 - 'v_in' = 3 - 'p_out' = 5 - 'v_out' = 3 - 'vban_in' = 8 - 'vban_out' = 8 + 'name' = 'potato' + 'p_in' = 5 + 'v_in' = 3 + 'p_out' = 5 + 'v_out' = 3 + 'asio_in' = 10 + 'asio_out' = 8 + 'composite' = 8 + 'insert' = 34 + 'vban_in' = 8 + 'vban_out' = 8 }; } function GetKind ([string]$kindId) { $KindMap[$kindId] -} +} \ No newline at end of file From 80869d4306a6f59322c50f419577f3f3dc054dc2 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Tue, 25 Nov 2025 21:25:13 -0500 Subject: [PATCH 4/7] tests pester tests pass --- tests/higher.Tests.ps1 | 26 ++++++++++++++++++++++++++ tests/run.ps1 | 2 ++ 2 files changed, 28 insertions(+) diff --git a/tests/higher.Tests.ps1 b/tests/higher.Tests.ps1 index 87f9397..0206ab7 100644 --- a/tests/higher.Tests.ps1 +++ b/tests/higher.Tests.ps1 @@ -110,6 +110,23 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.command.lock = $value } } + + Context 'Patch' { + It 'Should set and get Patch.insert[$insert]' -Skip:$ifBasic { + $vmr.patch.insert[$insert].set($value) + $vmr.patch.insert[$insert].get() | Should -Be $value + } + + It 'Should set and get Patch.postfadercomposite' -Skip:$ifBasic { + $vmr.patch.postfadercomposite = $value + $vmr.patch.postfadercomposite | Should -Be $value + } + + It 'Should set and get Patch.postfxinsert' -Skip:$ifBasic { + $vmr.patch.postfxinsert = $value + $vmr.patch.postfxinsert | Should -Be $value + } + } } Describe 'Float Tests' { @@ -241,6 +258,15 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } } + + Context 'Patch' { + It 'Should set and get Patch.composite[$composite]' -Skip:$ifBasic -ForEach @( + @{ Value = 22 }, @{ Value = 6 } + ) { + $vmr.patch.composite[$composite].set($value) + $vmr.patch.composite[$composite].get() | Should -Be $value + } + } } Describe 'String Tests' { diff --git a/tests/run.ps1 b/tests/run.ps1 index e6eafba..e6fa0a6 100644 --- a/tests/run.ps1 +++ b/tests/run.ps1 @@ -16,6 +16,8 @@ function main() { $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 + $insert = $vmr.kind.insert - 1 + $composite = $vmr.kind.composite - 1 # skip conditions by kind $ifBasic = $vmr.kind.name -eq 'basic' From 54319924d0902c7e942ad1277753b8e3609b6372 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Tue, 25 Nov 2025 21:57:15 -0500 Subject: [PATCH 5/7] update docs manual tests all pass: - asio[i].set($val) - asio[i].get() - outa2[i]-outa5[i].set($val) - outa2[i]-outa5[i].get() these require an asio device --- CHANGELOG.md | 1 + README.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5b9cfb..3ac4fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Before any major/minor/patch is released all test units will be run to verify th - IRemote base class - ArrayMember classes for array-like properties +- Patch class ## [3.3.0] - 2024-06-29 diff --git a/README.md b/README.md index 8754d0b..062c500 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,31 @@ $vmr.command.Load("path/to/filename.xml") $vmr.command.RunMacrobuttons() ``` +### Patch + +The following Patch commands are available: + +- postFaderComposite: bool +- Patch.postFxInsert: bool + +The following Patch methods are available: + +- asio[i].Set($val): int, from 0 to ASIO input channels +- OutA2[i]-OutA5[i].Set($val): int, from 0 to ASIO output channels +- composite[i].Set($val): int, from 0 to strip channels +- insert[i].Set($val): bool + +All members also have Get() available + +for example: + +```powershell +$vmr.asio[3].set(2) # patches ASIO input channel 2 (2) to strip 2, channel 2 (3) +$vmr.OutA3[0].set(24) # patches bus A3, channel 1 (0) to ASIO output channel 24 +$vmr.composite[5].set(0) # sets composite channel 6 (5) to default bus channel +$vmr.insert[4].get() +``` + ### Recorder The following commands are available: From f3ed1de55781b9732440ed06eac8eccf8c40bbe9 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Wed, 26 Nov 2025 09:30:44 -0500 Subject: [PATCH 6/7] Update README.md - correct postfxinsert - correct examples - better readability for patch arraymembers --- README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 062c500..e567f20 100644 --- a/README.md +++ b/README.md @@ -422,24 +422,22 @@ $vmr.command.RunMacrobuttons() The following Patch commands are available: - postFaderComposite: bool -- Patch.postFxInsert: bool +- postFxInsert: bool -The following Patch methods are available: +The following Patch members have .Set($val) and .Get() available: -- asio[i].Set($val): int, from 0 to ASIO input channels -- OutA2[i]-OutA5[i].Set($val): int, from 0 to ASIO output channels -- composite[i].Set($val): int, from 0 to strip channels -- insert[i].Set($val): bool - -All members also have Get() available +- asio[i]: int, from 0 to ASIO input channels +- OutA2[i]-OutA5[i]: int, from 0 to ASIO output channels +- composite[i]: int, from 0 to strip channels +- insert[i]: bool for example: ```powershell -$vmr.asio[3].set(2) # patches ASIO input channel 2 (2) to strip 2, channel 2 (3) -$vmr.OutA3[0].set(24) # patches bus A3, channel 1 (0) to ASIO output channel 24 -$vmr.composite[5].set(0) # sets composite channel 6 (5) to default bus channel -$vmr.insert[4].get() +$vmr.patch.asio[3].set(2) # patches ASIO input channel 2 (2) to strip 2, channel 2 (3) +$vmr.patch.OutA3[0].set(24) # patches bus A3, channel 1 (0) to ASIO output channel 24 +$vmr.patch.composite[5].set(0) # sets composite channel 6 (5) to default bus channel +$vmr.patch.insert[4].get() ``` ### Recorder From 15a977834d87f2f3f4945dd007d4531663067b70 Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:01:32 -0500 Subject: [PATCH 7/7] add a2 for basic patch.outa2[i] --- lib/kinds.ps1 | 2 +- lib/patch.ps1 | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/kinds.ps1 b/lib/kinds.ps1 index 7591f1a..e2cc224 100644 --- a/lib/kinds.ps1 +++ b/lib/kinds.ps1 @@ -6,7 +6,7 @@ $KindMap = @{ 'p_out' = 1 'v_out' = 1 'asio_in' = 4 - 'asio_out' = 0 + 'asio_out' = 8 'composite' = 0 'insert' = 0 'vban_in' = 4 diff --git a/lib/patch.ps1 b/lib/patch.ps1 index e0a512a..6a6e710 100644 --- a/lib/patch.ps1 +++ b/lib/patch.ps1 @@ -29,7 +29,10 @@ class Patch : IRemote { } hidden [void] AddASIOOutMembers () { - $num_A = $this.remote.kind.p_out + $num_A = $this.remote.kind.p_out + if ($this.remote.kind.name -eq 'basic') { + $num_A += $this.remote.kind.v_out + } $asio_out = $this.remote.kind.asio_out if ($asio_out -le 0) { return }