From 0d303e20be45ae8b6051e4c1dc9dac855d5fb8fe Mon Sep 17 00:00:00 2001 From: pblivingston <71585805+pblivingston@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:43:36 -0500 Subject: [PATCH] vban x.1.2.0 changes staged - on, name, ip partial write-only resolved - simple ranges of consecutive integers moved to AddIntMembers - audio instream/outstream divergent behavior separated - midi outstream route, string - new video outstream --- README.md | 54 +++++++- lib/kinds.ps1 | 6 +- lib/vban.ps1 | 286 ++++++++++++++++++----------------------- tests/higher.Tests.ps1 | 107 ++++++++++++--- tests/run.ps1 | 1 + 5 files changed, 269 insertions(+), 185 deletions(-) diff --git a/README.md b/README.md index f860d2f..4e0674e 100644 --- a/README.md +++ b/README.md @@ -465,22 +465,64 @@ The following Vban.instream | Vban.outstream properties are available: - on: bool - name: string - ip: string -- sr: in, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) -- channel: int from 1 to 8 -- bit: int, 16 or 24 -- quality: int, from 0 to 4 -- route: int, from 0 to 8 for example: ```powershell $vmr.vban.instream[0].on = $true -$vmr.vban.outstream[3].bit = 16 +$vmr.vban.outstream[9].ip = '192.168.1.154' ``` +##### audio + +The following audio Vban.instream | Vban.outstream properties are available: + +- sr: int, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) +- channel: int, from 1 to 8 +- bit: int, 16 or 24 +- quality: int, from 0 to 4 +- route: int, from 0 to 8 + SR, channel and bit are defined as readonly for instreams. Attempting to write to those parameters will throw an error. They are read and write for outstreams. +for example: + +```powershell +$vmr.vban.instream[0].route = 4 +$vmr.vban.outstream[3].bit = 16 +``` + +##### midi + +The following midi Vban.outstream[8] properties are available: + +- route: string, ('none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out') + +for example: + +```powershell +$vmr.vban.outstream[8].route = 'aux_in' +``` + +##### video + +The following video Vban.outstream[9] properties are available: + +- vfps: int, from 1 to 30 +- vformat: string, ('png', 'jpg') +- vquality: int, from 1 to 100 +- vcursor: bool +- route: int, from 0 to 4 + +for example: + +```powershell +$vmr.vban.outstream[9].vformat = 'jpg' +$vmr.vban.outstream[9].vquality = 85 +$vmr.vban.outstream[9].vcursor = $true +``` + ### Command Certain 'special' commands are defined by the API as performing actions rather than setting values. diff --git a/lib/kinds.ps1 b/lib/kinds.ps1 index 6f8e98f..9a4fc9a 100644 --- a/lib/kinds.ps1 +++ b/lib/kinds.ps1 @@ -9,7 +9,7 @@ $KindMap = @{ 'asio_out' = 8 'composite' = 0 'insert' = 0 - 'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1 } + 'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1; 'video' = 1 } 'eq_ch' = @{ 'strip' = 0; 'bus' = 0 } 'cells' = 0 'gainlayer' = 0 @@ -24,7 +24,7 @@ $KindMap = @{ 'asio_out' = 8 'composite' = 8 'insert' = 22 - 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 } + 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 } 'eq_ch' = @{ 'strip' = 0; 'bus' = 8 } 'cells' = 6 'gainlayer' = 0 @@ -39,7 +39,7 @@ $KindMap = @{ 'asio_out' = 8 'composite' = 8 'insert' = 34 - 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 } + 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 } 'eq_ch' = @{ 'strip' = 2; 'bus' = 8 } 'cells' = 6 'gainlayer' = 8 diff --git a/lib/vban.ps1 b/lib/vban.ps1 index 6444bfd..c496ecb 100644 --- a/lib/vban.ps1 +++ b/lib/vban.ps1 @@ -3,18 +3,14 @@ class Vban : IRemote { Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote) { $this.direction = $direction + + AddBoolMembers -PARAMS @('on') + AddStringMembers -PARAMS @('name', 'ip') } [string] identifier () { return 'vban.' + $this.direction + 'stream[' + $this.index + ']' } -} - -class VbanAudio : Vban { - VbanAudio ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { - AddBoolMembers -PARAMS @('on') - AddStringMembers -PARAMS @('name', 'ip') - } hidden $_port = $($this | Add-Member ScriptProperty 'port' ` { @@ -30,43 +26,33 @@ class VbanAudio : Vban { } } ) +} - hidden $_sr = $($this | Add-Member ScriptProperty 'sr' ` - { - [int]$this.Getter('sr') - } ` - { - param([int]$arg) - if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') } - else { - $opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) - if ($opts.Contains($arg)) { - $this._sr = $this.Setter('sr', $arg) - } - else { - Write-Warning ('Expected one of', $opts) - } - } - } - ) +class VbanAudio : Vban { + VbanAudio ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { + AddIntMembers -PARAMS @('quality', 'route') + } +} - hidden $_channel = $($this | Add-Member ScriptProperty 'channel' ` - { - [int]$this.Getter('channel') - } ` - { - param([int]$arg) - if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') } - else { - if ($arg -ge 1 -and $arg -le 8) { - $this._channel = $this.Setter('channel', $arg) - } - else { - Write-Warning ('Expected value from 1 to 8') - } - } - } - ) +class VbanMidi : Vban { + VbanMidi ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { + } +} + +class VbanText : Vban { + VbanText ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { + } +} + +class VbanVideo : Vban { + VbanVideo ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { + } +} + +class VbanInAudio : VbanAudio { + VbanInAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'in') { + AddIntMembers -ReadOnly -PARAMS @('sr', 'channel') + } hidden $_bit = $($this | Add-Member ScriptProperty 'bit' ` { @@ -74,125 +60,9 @@ class VbanAudio : Vban { return $val } ` { - param([int]$arg) - if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') } - else { - if (@(16, 24).Contains($arg)) { - $val = if ($arg -eq 16) { 1 } else { 2 } - $this._bit = $this.Setter('bit', $val) - } - else { - Write-Warning ('Expected value 16 or 24') - } - } + Write-Warning ("ERROR: $($this.identifier()).bit is read only") } ) - - hidden $_quality = $($this | Add-Member ScriptProperty 'quality' ` - { - [int]$this.Getter('quality') - } ` - { - param([int]$arg) - if ($arg -ge 0 -and $arg -le 4) { - $this._quality = $this.Setter('quality', $arg) - } - else { - Write-Warning ('Expected value from 0 to 4') - } - } - ) - - hidden $_route = $($this | Add-Member ScriptProperty 'route' ` - { - [int]$this.Getter('route') - } ` - { - param([int]$arg) - $rt = $this.remote.kind['p_' + $this.direction] + $this.remote.kind['v_' + $this.direction] - 1 - if ($arg -ge 0 -and $arg -le $rt) { - $this._route = $this.Setter('route', $arg) - } - else { - Write-Warning ("Expected value from 0 to $rt") - } - } - ) -} - -class VbanMidi : Vban { - VbanMidi ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { - } - - hidden $_on = $($this | Add-Member ScriptProperty 'on' ` - { - return Write-Warning ("ERROR: $($this.identifier()).on is write only") - } ` - { - param([bool]$arg) - $this._on = $this.Setter('on', $arg) - } - ) - - hidden $_name = $($this | Add-Member ScriptProperty 'name' ` - { - return Write-Warning ("ERROR: $($this.identifier()).name is write only") - } ` - { - param([string]$arg) - $this._name = $this.Setter('name', $arg) - } - ) - - hidden $_ip = $($this | Add-Member ScriptProperty 'ip' ` - { - return Write-Warning ("ERROR: $($this.identifier()).ip is write only") - } ` - { - param([string]$arg) - $this._ip = $this.Setter('ip', $arg) - } - ) -} - -class VbanText : Vban { - VbanText ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { - } - - hidden $_on = $($this | Add-Member ScriptProperty 'on' ` - { - return Write-Warning ("ERROR: $($this.identifier()).on is write only") - } ` - { - param([bool]$arg) - $this._on = $this.Setter('on', $arg) - } - ) - - hidden $_name = $($this | Add-Member ScriptProperty 'name' ` - { - return Write-Warning ("ERROR: $($this.identifier()).name is write only") - } ` - { - param([string]$arg) - $this._name = $this.Setter('name', $arg) - } - ) - - hidden $_ip = $($this | Add-Member ScriptProperty 'ip' ` - { - return Write-Warning ("ERROR: $($this.identifier()).ip is write only") - } ` - { - param([string]$arg) - $this._ip = $this.Setter('ip', $arg) - } - ) -} - -class VbanInAudio : VbanAudio { - VbanInAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'in') { - } } class VbanInMidi : VbanMidi { @@ -207,12 +77,103 @@ class VbanInText : VbanText { class VbanOutAudio : VbanAudio { VbanOutAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'out') { + AddIntMembers -PARAMS @('channel') } + + hidden $_sr = $($this | Add-Member ScriptProperty 'sr' ` + { + [int]$this.Getter('sr') + } ` + { + param([int]$arg) + $opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) + if ($opts.Contains($arg)) { + $this._sr = $this.Setter('sr', $arg) + } + else { + Write-Warning ('Expected one of', $opts) + } + } + ) + + hidden $_bit = $($this | Add-Member ScriptProperty 'bit' ` + { + $val = if ($this.Getter('bit') -eq 1) { 16 } else { 24 } + return $val + } ` + { + param([int]$arg) + if (@(16, 24).Contains($arg)) { + $val = if ($arg -eq 16) { 1 } else { 2 } + $this._bit = $this.Setter('bit', $val) + } + else { + Write-Warning ('Expected value 16 or 24') + } + } + ) } class VbanOutMidi : VbanMidi { VbanOutMidi ([int]$index, [Object]$remote) : base ($index, $remote, 'out') { } + + hidden $_route = $($this | Add-Member ScriptProperty 'route' ` + { + [string]$val = '' + switch ($this.Getter('route')) { + 0 { $val = 'none' } + 1 { $val = 'midi_in' } + 2 { $val = 'aux_in' } + 4 { $val = 'vban_in' } + 7 { $val = 'all_in' } + 8 { $val = 'midi_out' } + } + return $val + } ` + { + param([string]$arg) + [int]$val = 0 + switch ($arg) { + 'none' { $val = 0 } + 'midi_in' { $val = 1 } + 'aux_in' { $val = 2 } + 'vban_in' { $val = 4 } + 'all_in' { $val = 7 } + 'midi_out' { $val = 8 } + default { Write-Warning ("route got: $arg, expected one of 'none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out'") } + } + $this._route = $this.Setter('route', $val) + } + ) +} + +class VbanOutVideo : VbanVideo { + VbanOutVideo ([int]$index, [Object]$remote) : base ($index, $remote, 'out') { + AddIntMembers -PARAMS @('vfps', 'vquality', 'route') + AddBoolMembers -PARAMS @('vcursor') + } + + hidden $_vformat = $($this | Add-Member ScriptProperty 'vformat' ` + { + [string]$val = '' + switch ($this.Getter('vformat')) { + 1 { $val = 'png' } + 2 { $val = 'jpg' } + } + return $val + } ` + { + param([string]$arg) + [int]$val = 0 + switch ($arg) { + 'png' { $val = 1 } + 'jpg' { $val = 2 } + default { Write-Warning ("vformat got: $arg, expected one of 'png', 'jpg'") } + } + $this._vformat = $this.Setter('vformat', $val) + } + ) } function Make_Vban ([Object]$remote) { @@ -220,7 +181,7 @@ function Make_Vban ([Object]$remote) { [System.Collections.ArrayList]$outstream = @() $totalInstreams = $remote.kind.vban.in + $remote.kind.vban.midi + $remote.kind.vban.text - $totalOutstreams = $remote.kind.vban.out + $remote.kind.vban.midi + $totalOutstreams = $remote.kind.vban.out + $remote.kind.vban.midi + $remote.kind.vban.video for ($i = 0; $i -lt $totalInstreams; $i++) { if ($i -lt $remote.kind.vban.in) { @@ -237,9 +198,12 @@ function Make_Vban ([Object]$remote) { if ($i -lt $remote.kind.vban.out) { [void]$outstream.Add([VbanOutAudio]::new($i, $remote)) } - else { + elseif ($i -lt ($remote.kind.vban.out + $remote.kind.vban.midi)) { [void]$outstream.Add([VbanOutMidi]::new($i, $remote)) } + else { + [void]$outstream.Add([VbanOutVideo]::new($i, $remote)) + } } $CustomObject = [pscustomobject]@{ diff --git a/tests/higher.Tests.ps1 b/tests/higher.Tests.ps1 index 4ccb644..d215489 100644 --- a/tests/higher.Tests.ps1 +++ b/tests/higher.Tests.ps1 @@ -150,10 +150,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.vban.enable | Should -Be $expected } - Context 'Instream' -ForEach @( + Context 'Instream, audio, midi, text' -ForEach @( @{ Index = $vban_inA } - # @{ Index = $vban_inM } - # @{ Index = $vban_inT } + @{ Index = $vban_inM } + @{ Index = $vban_inT } ) { It "Should set vban.instream[$index].on" { $vmr.vban.instream[$index].on = $value @@ -161,15 +161,25 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } - Context 'Outstream' -ForEach @( + Context 'Outstream, audio, midi, video' -ForEach @( @{ Index = $vban_outA } - # @{ Index = $vban_outM } + @{ Index = $vban_outM } + @{ Index = $vban_outV } ) { It "Should set vban.outstream[$index].on" { $vmr.vban.outstream[$index].on = $value $vmr.vban.outstream[$index].on | Should -Be $expected } } + + Context 'Outstream, video only' -ForEach @( + @{ Index = $vban_outV } + ) { + It "Should set vban.outstream[$index].vcursor" { + $vmr.vban.outstream[$index].vcursor = $value + $vmr.vban.outstream[$index].vcursor | Should -Be $expected + } + } } Context 'Recorder' -Skip:$ifBasic { @@ -596,8 +606,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.vban.port | Should -Be $expected } - Context 'Instream' -ForEach @( + Context 'Instream, audio, midi, text' -ForEach @( @{ Index = $vban_inA } + @{ Index = $vban_inM } + @{ Index = $vban_inT } ) { It "Should set vban.instream[$index].port" -ForEach @( @{ Value = 1024; Expected = 1024 } @@ -608,16 +620,21 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { Start-Sleep -Milliseconds 2000 $vmr.vban.instream[$index].port | Should -Be $expected } + } - It "Should set vban.instream[$index].sr" { + Context 'Instream, audio only' -ForEach @( + @{ Index = $vban_inA } + ) { + + It "Should get vban.instream[$index].sr" { $vmr.vban.instream[$index].sr | Should -BeOfType [int] } - It "Should set vban.instream[$index].channel" { + It "Should get vban.instream[$index].channel" { $vmr.vban.instream[$index].channel | Should -BeOfType [int] } - It "Should set vban.instream[$index].bit" { + It "Should get vban.instream[$index].bit" { $vmr.vban.instream[$index].bit | Should -BeOfType [int] } @@ -639,8 +656,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } - Context 'Outstream' -ForEach @( + Context 'Outstream, audio, midi, video' -ForEach @( @{ Index = $vban_outA } + @{ Index = $vban_outM } + @{ Index = $vban_outV } ) { It "Should set vban.outstream[$index].port" -ForEach @( @{ Value = 1024; Expected = 1024 } @@ -651,6 +670,11 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { Start-Sleep -Milliseconds 2000 $vmr.vban.outstream[$index].port | Should -Be $expected } + } + + Context 'Outstream, audio only' -ForEach @( + @{ Index = $vban_outA } + ) { It "Should set vban.outstream[$index].sr" -ForEach @( @{ Value = 44100; Expected = 44100 } @@ -693,6 +717,46 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.vban.outstream[$index].route | Should -Be $expected } } + + Context 'Outstream, midi only' -ForEach @( + @{ Index = $vban_outM } + ) { + It "Should set vban.outstream[$index].route" -ForEach @( + @{ Value = 7; Expected = 7 } + @{ Value = 3; Expected = 3 } + ) { + $vmr.vban.outstream[$index].route = $value + $vmr.vban.outstream[$index].route | Should -Be $expected + } + } + + Context 'Outstream, video only' -ForEach @( + @{ Index = $vban_outV } + ) { + It "Should set vban.outstream[$index].vfps" -ForEach @( + @{ Value = 6; Expected = 6 } + @{ Value = 24; Expected = 24 } + ) { + $vmr.vban.outstream[$index].vfps = $value + $vmr.vban.outstream[$index].vfps | Should -Be $expected + } + + It "Should set vban.outstream[$index].vquality" -ForEach @( + @{ Value = 80; Expected = 80 } + @{ Value = 100; Expected = 100 } + ) { + $vmr.vban.outstream[$index].vquality = $value + $vmr.vban.outstream[$index].vquality | Should -Be $expected + } + + It "Should set vban.outstream[$index].route" -ForEach @( + @{ Value = 1; Expected = 1 } + @{ Value = 4; Expected = 4 } + ) { + $vmr.vban.outstream[$index].route = $value + $vmr.vban.outstream[$index].route | Should -Be $expected + } + } } Context 'Patch' { @@ -980,10 +1044,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } Describe 'Vban' { - Context 'Instream' -ForEach @( + Context 'Instream, audio, midi, text' -ForEach @( @{ Index = $vban_inA } - # @{ Index = $vban_inM } - # @{ Index = $vban_inT } + @{ Index = $vban_inM } + @{ Index = $vban_inT } ) { It "Should set vban.instream[$index].name" -ForEach @( @{ Value = 'TestIn0'; Expected = 'TestIn0' } @@ -1001,9 +1065,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } - Context 'Outstream' -ForEach @( + Context 'Outstream, audio, midi, video' -ForEach @( @{ Index = $vban_outA } - # @{ Index = $vban_outM } + @{ Index = $vban_outM } + @{ Index = $vban_outV } ) { It "Should set vban.outstream[$index].name" -ForEach @( @{ Value = 'TestOut0'; Expected = 'TestOut0' } @@ -1020,6 +1085,18 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.vban.outstream[$index].ip | Should -Be $expected } } + + Context 'Outstream, video only' -ForEach @( + @{ Index = $vban_outV } + ) { + It "Should set vban.outstream[$index].vformat" -ForEach @( + @{ Value = 'png'; Expected = 'png' } + @{ Value = 'jpg'; Expected = 'jpg' } + ) { + $vmr.vban.outstream[$index].vformat = $value + $vmr.vban.outstream[$index].vformat | Should -Be $expected + } + } } Context 'Recorder' -Skip:$ifBasic { diff --git a/tests/run.ps1 b/tests/run.ps1 index 0722af8..d01bffd 100644 --- a/tests/run.ps1 +++ b/tests/run.ps1 @@ -53,6 +53,7 @@ function main() { $vban_inT = $vmr.kind.vban.in + $vmr.kind.vban.midi + $vmr.kind.vban.text - 1 $vban_outA = $vmr.kind.vban.out - 1 $vban_outM = $vmr.kind.vban.out + $vmr.kind.vban.midi - 1 + $vban_outV = $vmr.kind.vban.out + $vmr.kind.vban.midi + $vmr.kind.vban.video - 1 $insert = $vmr.kind.insert - 1 $composite = $vmr.kind.composite - 1 $strip_ch = $vmr.kind.eq_ch['strip'] - 1