diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f32b2f..071c10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,28 @@ Before any major/minor/patch is released all unit tests will be run to verify th ## [Unreleased] These changes have not been added to PSGallery yet +### Added + +- Bus.EQ.Channel.Trim +- Bus.EQ.Channel.Delay + +- MIDI Vban.Outstream.Route: 'none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out' +- Video Vban.Outstream + - Vban.Outstream.Vfps + - Vban.Outstream.Vformat: 'png', 'jpg' + - Vban.Outstream.Vquality + - Vban.Outstream.Vcursor + - Vban.Outstream.Route (VMR bug: currently write-only) + +### Changed + +- `on`, `name`, `ip` now read/write on all streams +- Simple ranges of consecutive integers moved to `AddIntMembers` + - Retained warning for `sr` and anything with atypical behavior, consistent with the rest of the module + - Retained warning for `port` because Voicemeeter will allow this to be set below 1024 +- Audio instream/outstream divergent behavior via 'if' dropped in favor of explicit separation in derived classes + +- Updated EQ.Channel.Cell.Gain range in README ## [4.0.0] - 2025-12-16 diff --git a/README.md b/README.md index 09de82d..861374f 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ For past/future changes to this project refer to: [CHANGELOG](CHANGELOG.md) ## Tested against -- Basic 1.1.1.9 -- Banana 2.1.1.9 -- Potato 3.1.1.9 +- Basic 1.1.2.2 +- Banana 2.1.2.2 +- Potato 3.1.2.2 ## Requirements @@ -404,14 +404,21 @@ $vmr.strip[0].eq.on = $true $vmr.bus[0].eq.ab = $false ``` -##### channel.cell +##### channel + +The following bus.eq.channel.cell properties are available: + +- trim: float, from -24.00 to 24.00 +- delay: float, from 0.00 to 500.00 + +###### cell The following eq.channel.cell properties are available: - on: bool - type: int, from 0 to 6 - f: float, from 20.00 to 20000.00 -- gain: float, from -12.00 to 12.00 +- gain: float, from -36.00 to 18.00 - q: float, from 0.30 to 100.00 for example: @@ -458,22 +465,66 @@ 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 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 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 + +Route is currently write-only. This is a VMR bug. + +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/io.ps1 b/lib/io.ps1 index 5bbe38e..af42e2c 100644 --- a/lib/io.ps1 +++ b/lib/io.ps1 @@ -47,7 +47,7 @@ class IOEq : IRemote { $this.channel = @() for ($ch = 0; $ch -lt $remote.kind.eq_ch[$this.kindOfEq]; $ch++) { - $this.channel.Add([EqChannel]::new($ch, $remote, $this.identifier())) + $this.channel.Add([EqChannel]::new($ch, $this)) } } @@ -66,13 +66,15 @@ class EqChannel : IRemote { [System.Collections.ArrayList]$cell [string]$eqId - EqChannel ([int]$index, [Object]$remote, [string]$eqId) : base ($index, $remote) { - $this.eqId = $eqId + EqChannel ([int]$index, [Object]$eq) : base ($index, $eq.remote) { + $this.eqId = $eq.identifier() + + if ($eq.kindOfEq -eq 'Bus') { AddFloatMembers -PARAMS @('trim', 'delay') } $this.cell = @() $cellCount = $this.remote.kind.cells for ($c = 0; $c -lt $cellCount; $c++) { - $this.cell.Add([EqCell]::new($c, $remote, $this.identifier())) + $this.cell.Add([EqCell]::new($c, $this.remote, $this.identifier())) } } 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..1831235 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,104 @@ 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') + AddIntMembers -WriteOnly -PARAMS @('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 +182,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 +199,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 ab0c325..0d06d77 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 { @@ -465,19 +475,33 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { Context 'EQ' -Skip:$ifBasic -ForEach @( @{ Eq = $vmr.bus[$index].eq } ) { - It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].F" { - $eq.channel[$bus_ch].cell[$cells].f = $msHz - $eq.channel[$bus_ch].cell[$cells].f | Should -Be $msHz - } + Context "Channel[$bus_ch]" { + It "Should set Bus[$index].EQ.Channel[$bus_ch].Trim" { + $eq.channel[$bus_ch].trim = $slide + $eq.channel[$bus_ch].trim | Should -Be $slide + } - It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Gain" { - $eq.channel[$bus_ch].cell[$cells].gain = $slide - $eq.channel[$bus_ch].cell[$cells].gain | Should -Be $slide - } + It "Should set Bus[$index].EQ.Channel[$bus_ch].Delay" { + $eq.channel[$bus_ch].delay = $msHz + $eq.channel[$bus_ch].delay | Should -Be $msHz + } + + Context "Cell[$cells]" { + It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].F" { + $eq.channel[$bus_ch].cell[$cells].f = $msHz + $eq.channel[$bus_ch].cell[$cells].f | Should -Be $msHz + } - It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Q" { - $eq.channel[$bus_ch].cell[$cells].q = $knob - $eq.channel[$bus_ch].cell[$cells].q | Should -Be $knob + It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Gain" { + $eq.channel[$bus_ch].cell[$cells].gain = $slide + $eq.channel[$bus_ch].cell[$cells].gain | Should -Be $slide + } + + It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Q" { + $eq.channel[$bus_ch].cell[$cells].q = $knob + $eq.channel[$bus_ch].cell[$cells].q | Should -Be $knob + } + } } } } @@ -582,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 } @@ -594,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] } @@ -625,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 } @@ -637,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 } @@ -679,6 +717,34 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $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' { @@ -966,10 +1032,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' } @@ -987,9 +1053,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' } @@ -1006,6 +1073,31 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.vban.outstream[$index].ip | Should -Be $expected } } + + Context 'Outstream, midi only' -ForEach @( + @{ Index = $vban_outM } + ) { + It "Should set vban.outstream[$index].route" -ForEach @( + @{ Value = 'aux_in'; Expected = 'aux_in' } + @{ Value = 'all_in'; Expected = 'all_in' } + @{ Value = 'midi_out'; Expected = 'midi_out' } + ) { + $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].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 { @@ -1016,13 +1108,19 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.recorder.prefix = $prefix $vmr.recorder.filetype = $filetype + $start = Get-Date $vmr.recorder.state = 'record' - Start-Sleep -Milliseconds 10 - $stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date) $vmr.recorder.state | Should -Be 'record' Start-Sleep -Milliseconds 2000 - $tmp = [System.IO.Path]::Combine($recDir, ("{0} {1}.{2}" -f $prefix, $stamp, $filetype)) + $tmp = Get-ChildItem -Path $recDir -Filter ("{0}*.{1}" -f $prefix, $filetype) -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -gt $start } | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 + + if (-not $tmp) { + throw "'$filetype' file with prefix '$prefix' was not found in '$recDir'." + } $vmr.recorder.state = 'stop' $vmr.recorder.eject() @@ -1110,12 +1208,18 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } BeforeEach { + $start = Get-Date $vmr.recorder.record() - Start-Sleep -Milliseconds 10 - $stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date) Start-Sleep -Milliseconds 2000 - $tmp = [System.IO.Path]::Combine($recDir, ("{0} {1}.{2}" -f $prefix, $stamp, $filetype)) + $tmp = Get-ChildItem -Path $recDir -Filter ("{0}*.{1}" -f $prefix, $filetype) -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -gt $start } | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 + + if (-not $tmp) { + throw "'$filetype' file with prefix '$prefix' was not found in '$recDir'." + } $vmr.recorder.pause() Start-Sleep -Milliseconds 500 diff --git a/tests/run.ps1 b/tests/run.ps1 index 0722af8..bcd771c 100644 --- a/tests/run.ps1 +++ b/tests/run.ps1 @@ -11,12 +11,18 @@ function Test-RecDir ([object]$vmr, [string]$recDir) { try { + $start = Get-Date $vmr.recorder.record() - Start-Sleep -Milliseconds 10 - $stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date) Start-Sleep -Milliseconds 2000 - $tmp = Join-Path $recDir ("{0} {1}.{2}" -f $prefix, $stamp, $filetype) + $tmp = Get-ChildItem -Path $recDir -Filter ("{0}*.{1}" -f $prefix, $filetype) -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -gt $start } | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 + + if (-not $tmp) { + throw "'$filetype' file with prefix '$prefix' was not found in '$recDir'." + } $vmr.recorder.stop() $vmr.recorder.eject() @@ -53,6 +59,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