diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d82391..10a0784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ AddActionMembers now adds ScriptMethods instead of ScriptProperties: Deprecated Recorder.Loop removed: use Recorder.Mode.Loop Recorder.FileType changed from method to write-only property +Strip Gainlayers are now FloatArrayMember objects, see README for details + ### Added - IRemote base class @@ -43,6 +45,20 @@ Recorder.FileType changed from method to write-only property - Command.Save($filepath) - Command.StorePreset() - Command.RecallPreset() +- AddAliasMembers meta function takes a hashtable `-MAP` of `alias = property` +- Strip.Karaoke alias for Strip.K +- Strip.EQGain1|EQGain2|EQGain3 with bass/low, mid/med, treble/high aliases, respectively +- StripAudibility class with Strip.Audibility.Knob +- Strip.Denoiser.Threshold +- Strip.VAIO +- Strip.Pitch, StripPitch class + - on + - drywet + - pitchvalue + - loformant + - medformant + - hiformant + - recallpreset($presetIndex) ### Changed @@ -58,6 +74,10 @@ Recorder.FileType changed from method to write-only property - Recorder.Armstrip|Armbus -> BoolArrayMember: now have .Get() - Cast Recorder getters to types for consistency - Floats getters/setters now default to two decimal places. +- Strip.Mono is now an alias for Strip.MC on virtual strips +- Strip.AppMute|AppGain can now take an app index; see README for details +- Strip Knob setters: explicit $arg types for consistency +- Strip.Levels.Convert hidden and return type [float] -> [single] for naming consistency ### Fixed @@ -69,6 +89,9 @@ Recorder.FileType changed from method to write-only property - vban route range (API documentation is incorrect) - vban.stream.sr: $this._port -> $this._sr - Recorder.channel values: 1..8 -> (2, 4, 6, 8) +- Strip.Limit type [int] -> [float] +- Missing closing parenthesis in AppMute value string +- Strip Knob getters: `this.Getter_String('') -> [math]::Round($this.Getter(''), 2)` ## [3.3.0] - 2024-06-29 diff --git a/README.md b/README.md index 4a503dc..47b3956 100644 --- a/README.md +++ b/README.md @@ -118,11 +118,12 @@ The following strip commands are available: - mute: bool - mono: bool - mc: bool -- k: int, from 0 to 4 +- k/karaoke: int, from 0 to 4 - solo: bool - A1-A5: bool - B1-B3: bool -- limit: int, from -40 to 12 +- vaio: bool +- limit: float, from -40.00 to 12.00 - gain: float, from -60.00 to 12.00 - label: string - reverb: float, from 0.00 to 10.00 @@ -130,7 +131,7 @@ The following strip commands are available: - fx1: float, from 0.00 to 10.00 - fx2: float, from 0.00 to 10.00 - pan_x: float, from -0.50 to 0.50 -- pan_y: float, from 0.00 to 1.00 +- pan_y: float, physical: from 0.00 to 1.00, virtual: from -0.50 to 0.50 - color_x: float, from -0.50 to 0.50 - color_y: float, from 0.00 to 1.00 - fx_x: float, from -0.50 to 0.50 @@ -139,18 +140,22 @@ The following strip commands are available: - postdelay: bool - postfx1: bool - postfx2: bool -- gainlayer0-gainlayer7: float +- eqgain1/bass/low: float, from -12.00 to 12.00 +- eqgain2/mid/med: float, from -12.00 to 12.00 +- eqgain3/treble/high: float, from -12.00 to 12.00 for example: ```powershell -$vmr.strip[5].gainlayer1 = -8.3 +$vmr.strip[6].karaoke = 3 +$vmr.strip[0].limit = 4.5 +$vmr.strip[2].label = 'example' +$vmr.strip[7].pan_y = -0.38 +$vmr.strip[5].treble = -2.43 ``` A,B commands depend on Voicemeeter type. -gainlayers defined for Potato version only. - mc, k for virtual strips only. #### comp @@ -196,6 +201,7 @@ $vmr.strip[3].gate.threshold = -40.5 The following strip.denoiser commands are available: - knob: float, from 0.00 to 10.00 +- threshold: float, from 0.00 to 10.00 for example: @@ -203,16 +209,66 @@ for example: $vmr.strip[3].denoiser.knob = 5 ``` +#### pitch + +The following strip.pitch commands are available: + +- on: bool +- drywet: float, from -100.00 to 100.00 +- pitchvalue: float, from -12.00 to 12.00 +- loformant: float, from -12.00 to 12.00 +- medformant: float, from -12.00 to 12.00 +- hiformant: float, from -12.00 to 12.00 + +The following strip.pitch methods are available: + +- RecallPreset($presetIndex) : int, from 0 to 7 + +for example: + +```powershell +$vmr.strip[2].pitch.recallpreset(4) +$vmr.strip[4].pitch.drywet = -22.86 +$vmr.strip[1].pitch.medformant = 2.1 +``` + +#### audibility + +The following strip.audibility commands are available: + +- knob: float, from 0.00 to 10.00 + +for example: + +```powershell +$vmr.strip[1].audibility.knob = 2.66 +``` + +#### Gainlayer[i] + +The following strip.gainlayer[i] methods are available: + +- Set($val) : float, from -60.00 to 12.00 +- Get() + +for example: + +```powershell +$vmr.strip[4].gainlayer[7].set(-26.81) +``` + #### AppGain | AppMute -- `AppGain(amount, gain)` : string, float -- `AppMute(amount, mutestate)` : string, bool +- AppGain($appname or $appindex, $gain) : string or int, float, from 0.00 to 1.00 +- AppMute($appname or $appindex, $mutestate) : string or int, bool for example: ```powershell $vmr.strip[5].AppGain("Spotify", 0.5) $vmr.strip[5].AppMute("Spotify", $true) +$vmr.strip[7].AppGain(0, 0.28) +$vmr.strip[6].AppMute(2, $false) ``` #### levels diff --git a/lib/kinds.ps1 b/lib/kinds.ps1 index 059ae38..6f8e98f 100644 --- a/lib/kinds.ps1 +++ b/lib/kinds.ps1 @@ -12,6 +12,7 @@ $KindMap = @{ 'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1 } 'eq_ch' = @{ 'strip' = 0; 'bus' = 0 } 'cells' = 0 + 'gainlayer' = 0 }; 'banana' = @{ 'name' = 'banana' @@ -26,6 +27,7 @@ $KindMap = @{ 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 } 'eq_ch' = @{ 'strip' = 0; 'bus' = 8 } 'cells' = 6 + 'gainlayer' = 0 }; 'potato' = @{ 'name' = 'potato' @@ -40,6 +42,7 @@ $KindMap = @{ 'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 } 'eq_ch' = @{ 'strip' = 2; 'bus' = 8 } 'cells' = 6 + 'gainlayer' = 8 }; } diff --git a/lib/meta.ps1 b/lib/meta.ps1 index 4d69354..9d79186 100644 --- a/lib/meta.ps1 +++ b/lib/meta.ps1 @@ -74,6 +74,16 @@ function AddActionMembers () { } } +function AddAliasMembers () { + param( + [hashtable]$MAP + ) + foreach ($alias in $MAP.Keys) { + $this | Add-Member -MemberType AliasProperty -Name $alias ` + -Value $MAP[$alias] -Force + } +} + function AddChannelMembers () { $num_A = $this.remote.kind.p_out $num_B = $this.remote.kind.v_out @@ -86,21 +96,6 @@ function AddChannelMembers () { AddBoolMembers -PARAMS $channels } -function AddGainlayerMembers () { - [hashtable]$Signatures = @{} - 0..7 | ForEach-Object { - # Define getter - $Signatures['Getter'] = "`$this.Getter('gainlayer[{0}]')" -f $_ - # Define setter - $Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('gainlayer[{0}]', `$arg)" ` - -f $_ - $param = 'gainlayer{0}' -f $_ - $null = $param - - Addmember - } -} - function Addmember { $AddMemberParams = @{ Name = $param diff --git a/lib/strip.ps1 b/lib/strip.ps1 index 87062cc..6595322 100644 --- a/lib/strip.ps1 +++ b/lib/strip.ps1 @@ -1,16 +1,20 @@ class Strip : IRemote { + [System.Collections.ArrayList]$gainlayer [Object]$levels Strip ([int]$index, [Object]$remote) : base ($index, $remote) { - AddBoolMembers -PARAMS @('mono', 'solo', 'mute') - AddIntMembers -PARAMS @('limit') - AddFloatMembers -PARAMS @('gain', 'pan_x', 'pan_y') + AddBoolMembers -PARAMS @('solo', 'mute') + AddFloatMembers -PARAMS @('gain', 'limit', 'pan_x', 'pan_y') AddStringMembers -PARAMS @('label') AddChannelMembers - AddGainlayerMembers $this.levels = [StripLevels]::new($index, $remote) + + $this.gainlayer = @() + for ($i = 0; $i -lt $remote.kind.gainlayer; $i++) { + $this.gainlayer.Add([FloatArrayMember]::new($i, 'gainlayer', $this)) + } } [string] identifier () { @@ -42,7 +46,7 @@ class StripLevels : IRemote { } } - [float] Convert([float]$val) { + hidden [single] Convert([single]$val) { if ($val -gt 0) { return [math]::Round(20 * [math]::Log10($val), 1) } @@ -78,15 +82,20 @@ class PhysicalStrip : Strip { [Object]$denoiser [Object]$eq [Object]$device + [Object]$audibility + [Object]$pitch PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) { AddFloatMembers -PARAMS @('color_x', 'color_y', 'fx_x', 'fx_y') AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2') AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2') + AddBoolMembers -PARAMS @('mono', 'vaio') $this.comp = [StripComp]::new($index, $remote) $this.gate = [StripGate]::new($index, $remote) $this.denoiser = [StripDenoiser]::new($index, $remote) + $this.pitch = [StripPitch]::new($index, $remote) + $this.audibility = [StripAudibility]::new($index, $remote) $this.eq = [StripEq]::new($index, $remote) $this.device = [StripDevice]::new($index, $remote) } @@ -104,10 +113,10 @@ class StripComp : IRemote { hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` { - $this.Getter_String('') + [math]::Round($this.Getter(''), 2) } ` { - param($arg) + param([single]$arg) return $this.Setter('', $arg) } ) @@ -124,10 +133,10 @@ class StripGate : IRemote { hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` { - $this.Getter_String('') + [math]::Round($this.Getter(''), 2) } ` { - param($arg) + param([single]$arg) return $this.Setter('', $arg) } ) @@ -135,6 +144,7 @@ class StripGate : IRemote { class StripDenoiser : IRemote { StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) { + AddFloatMembers -PARAMS @('threshold') } [string] identifier () { @@ -143,10 +153,44 @@ class StripDenoiser : IRemote { hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` { - $this.Getter_String('') + [math]::Round($this.Getter(''), 2) } ` { - param($arg) + param([single]$arg) + return $this.Setter('', $arg) + } + ) +} + +class StripPitch : IRemote { + StripPitch ([int]$index, [Object]$remote) : base ($index, $remote) { + AddBoolMembers -PARAMS @('on') + AddFloatMembers -PARAMS @('drywet', 'pitchvalue', 'loformant', 'medformant', 'hiformant') + } + + [string] identifier () { + return 'Strip[' + $this.index + '].Pitch' + } + + [void] RecallPreset ([int]$presetIndex) { + $this.Setter('RecallPreset', $presetIndex) + } +} + +class StripAudibility : IRemote { + StripAudibility ([int]$index, [Object]$remote) : base ($index, $remote) { + } + + [string] identifier () { + return 'Strip[' + $this.index + '].Audibility' + } + + hidden $_knob = $($this | Add-Member ScriptProperty 'knob' ` + { + [math]::Round($this.Getter(''), 2) + } ` + { + param([single]$arg) return $this.Setter('', $arg) } ) @@ -174,14 +218,34 @@ class VirtualStrip : Strip { VirtualStrip ([int]$index, [Object]$remote) : base ($index, $remote) { AddBoolMembers -PARAMS @('mc') AddIntMembers -PARAMS @('k') + AddFloatMembers -PARAMS @('eqgain1', 'eqgain2', 'eqgain3') + + AddAliasMembers -MAP @{ + mono = 'mc' + karaoke = 'k' + bass = 'eqgain1' + low = 'eqgain1' + mid = 'eqgain2' + med = 'eqgain2' + treble = 'eqgain3' + high = 'eqgain3' + } } [void] AppGain ([string]$appname, [single]$gain) { $this.Setter('AppGain', "(`"$appname`", $gain)") } + [void] AppGain ([int]$appindex, [single]$gain) { + $this.Setter("App[$appindex].Gain", $gain) + } + [void] AppMute ([string]$appname, [bool]$mutestate) { - $this.Setter('AppMute', "(`"$appname`", $(if ($mutestate) { 1 } else { 0 })") + $this.Setter('AppMute', "(`"$appname`", $(if ($mutestate) { 1 } else { 0 }))") + } + + [void] AppMute ([int]$appindex, [bool]$mutestate) { + $this.Setter("App[$appindex].Mute", $mutestate) } } diff --git a/tests/higher.Tests.ps1 b/tests/higher.Tests.ps1 index 431b8c6..ab0c325 100644 --- a/tests/higher.Tests.ps1 +++ b/tests/higher.Tests.ps1 @@ -30,6 +30,23 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { Context 'Strip, physical only' -ForEach @( @{ Index = $phys_in } ) { + It "Should set Strip[$index].Mono" { + $vmr.strip[$index].mono = $value + $vmr.strip[$index].mono | Should -Be $expected + } + + It "Should set Strip[$index].VAIO" { + $vmr.strip[$index].vaio = $value + $vmr.strip[$index].vaio | Should -Be $expected + } + + Context 'Pitch' -Skip:$ifNotPotato { + It "Should set Strip[$index].Pitch.On" { + $vmr.strip[$index].pitch.on = $value + $vmr.strip[$index].pitch.on | Should -Be $expected + } + } + Context 'Eq' -Skip:$ifNotPotato -ForEach @( @{ Eq = $vmr.strip[$index].eq } ) { @@ -50,6 +67,15 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } + Context 'Strip, first virtual' -ForEach @( + @{ Index = $phys_in + 1 } + ) { + It "Should set Strip[$index].MC via alias 'Mono'" { + $vmr.strip[$index].mono = $value + $vmr.strip[$index].mc | Should -Be $expected + } + } + Context 'Bus, one physical one virtual' -ForEach @( @{ Index = $phys_out }, @{ Index = $virt_out } ) { @@ -246,7 +272,7 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { Describe 'Float Tests' -Tag 'float' -ForEach @( @{ Gain = -24.63; Knob = 5.27; Slide = -7.51; Xy10 = 0.83; Xy05 = -0.42; MsHz = 196.57 } - @{ Gain = -12.48; Knob = 8.91; Slide = 3.14; Xy10 = 0.27; Xy05 = 0.69; MsHz = 142.13 } + @{ Gain = -12.48; Knob = 8.91; Slide = 3.14; Xy10 = 0.27; Xy05 = 0.29; MsHz = 142.13 } ) { Context 'Strip, one physical one virtual' -ForEach @( @{ Index = $phys_in }, @{ Index = $virt_in } @@ -255,11 +281,30 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.strip[$index].gain = $gain $vmr.strip[$index].gain | Should -Be $gain } + + It "Should set Strip[$index].Limit" -Skip:$ifBasic { + $vmr.strip[$index].limit = $gain + $vmr.strip[$index].limit | Should -Be $gain + } + + Context 'Gainlayers' -Skip:$ifNotPotato -ForEach @( + @{ Layer = $phys_out }, @{ Layer = $virt_out } + ) { + It "Should set Strip[$index].Gainlayer[$layer]" { + $vmr.strip[$index].gainlayer[$layer].set($gain) + $vmr.strip[$index].gainlayer[$layer].get() | Should -Be $gain + } + } } Context 'Strip, physical only' -ForEach @( @{ Index = $phys_in } ) { + It "Should set Strip[$index].Pan_Y" { + $vmr.strip[$index].pan_y = $xy10 + $vmr.strip[$index].pan_y | Should -Be $xy10 + } + Context 'Comp, Gate' -Skip:$ifBasic { It "Should set Strip[$index].Comp" { $vmr.strip[$index].comp.knob = $knob @@ -301,6 +346,45 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { $vmr.strip[$index].denoiser.knob = $knob $vmr.strip[$index].denoiser.knob | Should -Be $knob } + + It "Should set Strip[$index].Denoiser.Threshold" { + $vmr.strip[$index].denoiser.threshold = $knob + $vmr.strip[$index].denoiser.threshold | Should -Be $knob + } + } + + Context 'Pitch' -Skip:$ifNotPotato { + It "Should set Strip[$index].Pitch.drywet" { + $vmr.strip[$index].pitch.drywet = $slide + $vmr.strip[$index].pitch.drywet | Should -Be $slide + } + + It "Should set Strip[$index].Pitch.pitchvalue" { + $vmr.strip[$index].pitch.pitchvalue = $slide + $vmr.strip[$index].pitch.pitchvalue | Should -Be $slide + } + + It "Should set Strip[$index].Pitch.loformant" { + $vmr.strip[$index].pitch.loformant = $slide + $vmr.strip[$index].pitch.loformant | Should -Be $slide + } + + It "Should set Strip[$index].Pitch.medformant" { + $vmr.strip[$index].pitch.medformant = $slide + $vmr.strip[$index].pitch.medformant | Should -Be $slide + } + + It "Should set Strip[$index].Pitch.hiformant" { + $vmr.strip[$index].pitch.hiformant = $slide + $vmr.strip[$index].pitch.hiformant | Should -Be $slide + } + } + + Context 'Audibility' -Skip:$ifNotBasic { + It "Should set Strip[$index].Audibility" { + $vmr.strip[$index].audibility.knob = $knob + $vmr.strip[$index].audibility.knob | Should -Be $knob + } } Context 'EQ' -Skip:$ifNotPotato -ForEach @( @@ -323,6 +407,53 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } + Context 'Strip, virtual only' -ForEach @( + @{ Index = $virt_in } + ) { + It "Should set Strip[$index].Pan_Y" { + $vmr.strip[$index].pan_y = $xy05 + $vmr.strip[$index].pan_y | Should -Be $xy05 + } + + Context 'EQ' { + BeforeEach { + $vmr.strip[$index].eqgain1 = 0 + $vmr.strip[$index].eqgain2 = 0 + $vmr.strip[$index].eqgain3 = 0 + } + + It "Should set Strip[$index].EQGain1 via alias 'bass'" { + $vmr.strip[$index].bass = $slide + $vmr.strip[$index].eqgain1 | Should -Be $slide + } + + It "Should set Strip[$index].EQGain1 via alias 'low'" { + $vmr.strip[$index].low = $slide + $vmr.strip[$index].eqgain1 | Should -Be $slide + } + + It "Should set Strip[$index].EQGain2 via alias 'mid'" { + $vmr.strip[$index].mid = $slide + $vmr.strip[$index].eqgain2 | Should -Be $slide + } + + It "Should set Strip[$index].EQGain2 via alias 'med'" { + $vmr.strip[$index].med = $slide + $vmr.strip[$index].eqgain2 | Should -Be $slide + } + + It "Should set Strip[$index].EQGain3 via alias 'treble'" { + $vmr.strip[$index].treble = $slide + $vmr.strip[$index].eqgain3 | Should -Be $slide + } + + It "Should set Strip[$index].EQGain3 via alias 'high'" { + $vmr.strip[$index].high = $slide + $vmr.strip[$index].eqgain3 | Should -Be $slide + } + } + } + Context 'Bus, one physical one virtual' -ForEach @( @{ Index = $phys_out }, @{ Index = $virt_out } ) { @@ -362,18 +493,6 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } Describe 'Int Tests' -Tag 'int' { - Context 'Strip, one physical, one virtual' -ForEach @( - @{ Index = $phys_in }, @{ Index = $virt_in } - ) { - It "Should set and get Strip[$index].Limit" -Skip:$ifBasic -ForEach @( - @{ Value = 3; Expected = 3 } - @{ Value = -6; Expected = -6 } - ) { - $vmr.strip[$index].limit = $value - $vmr.strip[$index].limit | Should -Be $expected - } - } - Context 'Strip, physical only' -ForEach @( @{ Index = $phys_in } ) { @@ -395,6 +514,19 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' { } } + Context 'Strip, second virtual' -Skip:$ifBasic -ForEach @( + @{ Index = $phys_in + 2 } + ) { + It "Should set Strip[$index].K via alias 'Karaoke'" -ForEach @( + @{ Value = 0; Expected = 0 } + @{ Value = 2; Expected = 2 } + @{ Value = 4; Expected = 4 } + ) { + $vmr.strip[$index].karaoke = $value + $vmr.strip[$index].k | Should -Be $expected + } + } + Context 'Bus, one physical one virtual' -ForEach @( @{ Index = $phys_out }, @{ Index = $virt_out } ) {