12 Commits

Author SHA1 Message Date
f480b637eb pester test script added to launch.json
CHANGELOG, README updated
2023-08-14 23:01:38 +01:00
09078d382b make examples and tests runnable if dot sourced 2023-08-14 22:44:09 +01:00
598e0dd647 add launch scripts 2023-08-14 21:45:18 +01:00
72b5ac02d3 adds missing Recorder parameters 2023-08-14 21:43:51 +01:00
a031d25a41 fix range checks 2023-08-14 21:30:32 +01:00
4e9ff66640 rework getters, setters in higher classes 2023-08-12 03:09:23 +01:00
bee52b6541 rename some of the internal classes
RecorderMode class added to Recorder

RunMacrobuttons() and CloseMacrobuttons() added to Special (Command)
2023-08-12 01:40:29 +01:00
5bda43131b upd changelog 2023-08-09 14:44:47 +01:00
1c9c400f12 VBVMR_GetLevel binding added
Get_Level implemented in base.ps1

strip.{PreFader,PostFader,PostMute} methods added

bus.{All} added
2023-08-09 14:16:27 +01:00
aee3430962 fix strip[i].device.name bug
patch bump
2022-12-19 23:19:20 +00:00
47fb880b91 remove tasklist from unreleased 2022-12-19 00:45:13 +00:00
acc078632d add strip.eq/bus.eq example to readme 2022-12-18 18:52:22 +00:00
15 changed files with 713 additions and 311 deletions

63
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,63 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "PowerShell: Launch CLI Example",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}/examples/cli",
"script": "${workspaceFolder}/examples/cli/CLI.ps1",
"args": [
"-s",
"\"strip[0].mute\",",
"\"!strip[0].mute\",",
"\"strip[0].mute\",",
"\"bus[2].eq.on=1\",",
"\"command.lock=1\""
],
"createTemporaryIntegratedConsole": true
},
{
"name": "PowerShell: Launch NextBus Example",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}/examples/nextbus",
"script": "${workspaceFolder}/examples/nextbus/GoTo-NextBus.ps1",
"args": [],
"createTemporaryIntegratedConsole": true
},
{
"name": "PowerShell: Launch OBS Example",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}/examples/obs",
"script": "${workspaceFolder}/examples/obs/Vm-Obs-Sync.ps1",
"args": [],
"createTemporaryIntegratedConsole": true
},
{
"name": "PowerShell: Run Pester Tests",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}",
"script": "${workspaceFolder}/tests/pre-commit.ps1",
"args": [],
"createTemporaryIntegratedConsole": true
},
{
"name": "PowerShell: Launch Quick Test",
"type": "PowerShell",
"request": "launch",
"cwd": "${workspaceRoot}",
"script": "${workspaceFolder}/quick.ps1",
"args": [
"-Verbose",
"-Debug"
],
"createTemporaryIntegratedConsole": true
}
]
}

View File

@@ -9,10 +9,8 @@ Before any major/minor/patch is released all test units will be run to verify th
## [Unreleased] These changes have not been added to PSGallery yet ## [Unreleased] These changes have not been added to PSGallery yet
- [x] Implement command.load - [x] Level methods for Strip,Bus classes implemented.
- [x] Implement comp/gate parameters introduced in v3.0.2.8 of the api. - [x] More Recorder commands implemented.
- [x] Add unit tests for new classes.
- [x] Update README with changes to Strip/Bus classes.
## [3.0.0] ## [3.0.0]

View File

@@ -79,7 +79,7 @@ Voicemeeter factory function can be:
- Get-RemoteBanana - Get-RemoteBanana
- Get-RemotePotato - Get-RemotePotato
Added in v3 you may also use the following entry/exit points: Added in `v3` you may also use the following entry/exit points:
- Connect-Voicemeeter - Connect-Voicemeeter
- Disconnect-Voicemeeter - Disconnect-Voicemeeter
@@ -90,6 +90,8 @@ for example:
```powershell ```powershell
$vmr = Connect-Voicemeeter -Kind "potato" $vmr = Connect-Voicemeeter -Kind "potato"
...
Disconnect-Voicemeeter
``` ```
#### `Through the Shell` #### `Through the Shell`
@@ -213,6 +215,20 @@ $vmr.strip[5].AppGain("Spotify", 0.5)
$vmr.strip[5].AppMute("Spotify", $true) $vmr.strip[5].AppMute("Spotify", $true)
``` ```
#### levels
The following strip.level commands are available:
- PreFader()
- PostFader()
- PostMute()
for example:
```powershell
$vmr.strip[2].levels.PreFader() -Join ', ' | Write-Host
```
### Bus ### Bus
The following bus commands are available: The following bus commands are available:
@@ -262,6 +278,18 @@ $vmr.bus[0].mode.centeronly = $true
$vmr.bus[0].mode.Get() $vmr.bus[0].mode.Get()
``` ```
#### levels
The following strip.level commands are available:
- All()
for example:
```powershell
$vmr.bus[2].levels.All() -Join ', ' | Write-Host
```
### Strip|Bus ### Strip|Bus
#### device #### device
@@ -292,6 +320,13 @@ The following strip.eq | bus.eq commands are available:
- on: boolean - on: boolean
- ab: boolean - ab: boolean
for example:
```powershell
$vmr.strip[0].eq.on = $true
$vmr.bus[0].eq.ab = $false
```
#### FadeTo | FadeBy #### FadeTo | FadeBy
- `FadeTo(amount, time)` : float, int - `FadeTo(amount, time)` : float, int
@@ -355,18 +390,18 @@ $vmr.vban.outstream[3].bit = 16
Certain 'special' commands are defined by the API as performing actions rather than setting values. Certain 'special' commands are defined by the API as performing actions rather than setting values.
The following methods are available: The following commands are available:
- show - show
- hide - hide
- restart - restart
- shutdown - shutdown
- Load(filepath) - showvbanchat: boolean (write only)
- lock: boolean (write only)
The following properties are write only and accept boolean values: The following methods are available:
- showvbanchat - Load($filepath): string
- lock
example: example:
@@ -380,7 +415,7 @@ $vmr.command.Load("path/to/filename.xml")
### Recorder ### Recorder
The following methods are available: The following commands are available:
- play - play
- stop - stop
@@ -388,19 +423,53 @@ The following methods are available:
- record - record
- ff - ff
- rew - rew
- A1 - A5: boolean
- B1 - B3: boolean
- samplerate: int (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
- bitresolution: int (8, 16, 24, 32)
- channel: int from 1 to 8
- kbps: int (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
The following properties accept boolean values. The following methods are available:
- loop - Load($filepath): string
- A1 - A5 - GoTo($timestring): string, must match the format 'hh:mm:ss'
- B1 - B3 - FileType($format): string, ('wav', 'aiff', 'bwf', 'mp3')
example: example:
```powershell ```powershell
$vmr.recorder.play $vmr.recorder.play
$vmr.recorder.A1 = $true
$vmr.recorder.loop = $true $vmr.recorder.GoTo("00:01:15") # go to 1min 15sec into track
```
#### Mode
The following commands are available:
- recbus
- playonload
- loop
- multitrack
example:
```powershell
$vmr.recorder.mode.loop = $true
```
#### ArmStrip[i]|ArmBus[i]
The following method is available:
- Set($val): boolean
example:
```powershell
$vmr.recorder.armstrip[0].Set($true)
``` ```
### Multiple parameters ### Multiple parameters

View File

@@ -63,4 +63,4 @@ function main {
finally { Disconnect-Voicemeeter } finally { Disconnect-Voicemeeter }
} }
if ($MyInvocation.InvocationName -ne '.') { main } main

View File

@@ -68,4 +68,4 @@ function main {
} }
} }
if ($MyInvocation.InvocationName -ne '.') { main } main

View File

@@ -75,7 +75,7 @@ class RemoteBasic : Remote {
$this.bus = Make_Buses($this) $this.bus = Make_Buses($this)
$this.button = Make_Buttons $this.button = Make_Buttons
$this.vban = Make_Vban($this) $this.vban = Make_Vban($this)
$this.command = Make_Command $this.command = Make_Command($this)
} }
} }
@@ -92,7 +92,7 @@ class RemoteBanana : Remote {
$this.bus = Make_Buses($this) $this.bus = Make_Buses($this)
$this.button = Make_Buttons $this.button = Make_Buttons
$this.vban = Make_Vban($this) $this.vban = Make_Vban($this)
$this.command = Make_Command $this.command = Make_Command($this)
$this.recorder = Make_Recorder($this) $this.recorder = Make_Recorder($this)
} }
} }
@@ -110,7 +110,7 @@ class RemotePotato : Remote {
$this.bus = Make_Buses($this) $this.bus = Make_Buses($this)
$this.button = Make_Buttons $this.button = Make_Buttons
$this.vban = Make_Vban($this) $this.vban = Make_Vban($this)
$this.command = Make_Command $this.command = Make_Command($this)
$this.recorder = Make_Recorder($this) $this.recorder = Make_Recorder($this)
} }
} }

View File

@@ -203,3 +203,18 @@ function Set_By_Script {
Write-Warning $_.Exception.ErrorMessage() Write-Warning $_.Exception.ErrorMessage()
} }
} }
function Get_Level {
param(
[int64]$MODE, [int64]$INDEX
)
New-Variable -Name ptr -Value 0.0
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr)
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
}
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
}
[float]$ptr
}

View File

@@ -1,6 +1,6 @@
function Setup_DLL { function Setup_DLL {
try { try {
$vb_path = Get_VBPath $vb_path = Get_VMPath
if ([string]::IsNullOrWhiteSpace($vb_path)) { if ([string]::IsNullOrWhiteSpace($vb_path)) {
throw [VMRemoteError]::new("couldn't get Voicemeeter path") throw [VMRemoteError]::new("couldn't get Voicemeeter path")
@@ -47,6 +47,9 @@ function Setup_DLL {
[DllImport(@"$dll")] [DllImport(@"$dll")]
public static extern int VBVMR_SetParameters(String param); public static extern int VBVMR_SetParameters(String param);
[DllImport(@"$dll")]
public static extern int VBVMR_GetLevel(Int64 mode, Int64 index, ref float ptr);
"@ "@
Add-Type -MemberDefinition $Signature -Name Remote -Namespace Voicemeeter -PassThru | Out-Null Add-Type -MemberDefinition $Signature -Name Remote -Namespace Voicemeeter -PassThru | Out-Null

View File

@@ -18,29 +18,31 @@ class IBus {
} }
[single] Getter ($param) { [single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false return $this.remote.Getter("$($this.identifier()).$param")
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true return $this.remote.Getter_String("$($this.identifier()).$param")
} }
[void] Setter ($param, $set) { [void] Setter ($param, $val) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $set $this.remote.Setter("$($this.identifier()).$param", $val)
} }
} }
class Bus : IBus { class Bus : IBus {
[Object]$mode [Object]$mode
[Object]$eq [Object]$eq
[Object]$levels
Bus ([int]$index, [Object]$remote) : base ($index, $remote) { Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('mono', 'mute') AddBoolMembers -PARAMS @('mono', 'mute')
AddStringMembers -PARAMS @('label') AddStringMembers -PARAMS @('label')
AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2') AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
$this.mode = [Mode]::new($index, $remote) $this.mode = [BusMode]::new($index, $remote)
$this.eq = [Eq]::new($index, $remote) $this.eq = [BusEq]::new($index, $remote)
$this.levels = [BusLevels]::new($index, $remote)
} }
[void] FadeTo ([single]$target, [int]$time) { [void] FadeTo ([single]$target, [int]$time) {
@@ -52,10 +54,41 @@ class Bus : IBus {
} }
} }
class Mode : IBus { class BusLevels : IBus {
[int]$init
[int]$offset
BusLevels ([int]$index, [Object]$remote) : base ($index, $remote) {
$this.init = $index * 8
$this.offset = 8
}
[float] Convert([float]$val) {
if ($val -gt 0) {
return [math]::Round(20 * [math]::Log10($val), 1)
}
else {
return - 200.0
}
}
[System.Collections.ArrayList] Getter([int]$mode) {
[System.Collections.ArrayList]$vals = @()
$this.init..$($this.init + $this.offset - 1) | ForEach-Object {
$vals.Add($this.Convert($(Get_Level -MODE $mode -INDEX $_)))
}
return $vals
}
[System.Collections.ArrayList] All() {
return $this.Getter(3)
}
}
class BusMode : IBus {
[System.Collections.ArrayList]$modes [System.Collections.ArrayList]$modes
Mode ([int]$index, [Object]$remote) : base ($index, $remote) { BusMode ([int]$index, [Object]$remote) : base ($index, $remote) {
$this.modes = @( $this.modes = @(
'normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21', 'upmix41', 'upmix61', 'normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21', 'upmix41', 'upmix61',
'centeronly', 'lfeonly', 'rearonly' 'centeronly', 'lfeonly', 'rearonly'
@@ -78,8 +111,8 @@ class Mode : IBus {
} }
} }
class Eq : IBus { class BusEq : IBus {
Eq ([int]$index, [Object]$remote) : base ($index, $remote) { BusEq ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('on', 'ab') AddBoolMembers -PARAMS @('on', 'ab')
} }
@@ -92,12 +125,12 @@ class PhysicalBus : Bus {
[Object]$device [Object]$device
PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) { PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) {
$this.device = [Device]::new($index, $remote) $this.device = [BusDevice]::new($index, $remote)
} }
} }
class Device : IBus { class BusDevice : IBus {
Device ([int]$index, [Object]$remote) : base ($index, $remote) { BusDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
} }
[string] identifier () { [string] identifier () {

View File

@@ -1,8 +1,13 @@
. $PSScriptRoot\meta.ps1 . $PSScriptRoot\meta.ps1
. $PSScriptRoot\inst.ps1
class Special { class Special {
Special () { [Object]$remote
Special ([Object]$remote) {
AddActionMembers -PARAMS @('restart', 'shutdown', 'show') AddActionMembers -PARAMS @('restart', 'shutdown', 'show')
$this.remote = $remote
} }
[string] identifier () { [string] identifier () {
@@ -14,18 +19,26 @@ class Special {
} }
[single] Getter ($param) { [single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false return $this.remote.Getter("$($this.identifier()).$param")
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
if ($val -is [Boolean]) { if ($val -is [Boolean]) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 }) $this.remote.Setter("$($this.identifier()).$param", $(if ($val) { 1 } else { 0 }))
} }
else { else {
Param_Set -PARAM "$($this.identifier()).$param" -Value $val $this.remote.Setter("$($this.identifier()).$param", $val)
} }
} }
[void] RunMacrobuttons() {
Start-Process -FilePath $(Join-Path -Path $(Get_VMPath) -ChildPath "VoicemeeterMacroButtons.exe")
}
[void] CloseMacrobuttons() {
Stop-Process -Name "VoicemeeterMacroButtons"
}
hidden $_hide = $($this | Add-Member ScriptProperty 'hide' ` hidden $_hide = $($this | Add-Member ScriptProperty 'hide' `
{ {
$this._hide = $this.Setter('show', $false) $this._hide = $this.Setter('show', $false)
@@ -58,6 +71,6 @@ class Special {
} }
} }
function Make_Command { function Make_Command([Object]$remote) {
return [Special]::new() return [Special]::new($remote)
} }

View File

@@ -1,4 +1,4 @@
function Get_VBPath { function Get_VMPath {
$reg_path = "Registry::HKEY_LOCAL_MACHINE\Software" + ` $reg_path = "Registry::HKEY_LOCAL_MACHINE\Software" + `
(& { if ([Environment]::Is64BitOperatingSystem) { "\WOW6432Node" } else { "" } }) + ` (& { if ([Environment]::Is64BitOperatingSystem) { "\WOW6432Node" } else { "" } }) + `
"\Microsoft\Windows\CurrentVersion\Uninstall" "\Microsoft\Windows\CurrentVersion\Uninstall"

View File

@@ -1,12 +1,54 @@
. $PSScriptRoot\meta.ps1 . $PSScriptRoot\meta.ps1
class Recorder { class IRecorder {
[Object]$remote [Object]$remote
Recorder ([Object]$remote) { IRecorder ([Object]$remote) {
$this.remote = $remote $this.remote = $remote
}
[single] Getter ($param) {
$this.Cmd($param) | Write-Debug
return $this.remote.Getter($this.Cmd($param))
}
[void] Setter ($param, $val) {
"$($this.Cmd($param))=$val" | Write-Debug
if ($val -is [Boolean]) {
$this.remote.Setter($this.Cmd($param), $(if ($val) { 1 } else { 0 }))
}
else {
$this.remote.Setter($this.Cmd($param), $val)
}
}
[string] Cmd ($param) {
if ([string]::IsNullOrEmpty($param)) {
return $this.identifier()
}
return "$($this.identifier()).$param"
}
}
class Recorder : IRecorder {
[Object]$remote
[Object]$mode
[System.Collections.ArrayList]$armstrip
[System.Collections.ArrayList]$armbus
Recorder ([Object]$remote) : base ($remote) {
$this.mode = [RecorderMode]::new($remote)
$this.armstrip = @()
0..($remote.kind.p_in + $remote.kind.v_in - 1) | ForEach-Object {
$this.armstrip.Add([RecorderArmStrip]::new($_, $remote))
}
$this.armbus = @()
0..($remote.kind.p_out + $remote.kind.v_out - 1) | ForEach-Object {
$this.armbus.Add([RecorderArmBus]::new($_, $remote))
}
AddActionMembers -PARAMS @('play', 'stop', 'pause', 'replay', 'record', 'ff', 'rew') AddActionMembers -PARAMS @('play', 'stop', 'pause', 'replay', 'record', 'ff', 'rew')
AddFloatMembers -PARAMS @('gain')
AddChannelMembers AddChannelMembers
} }
@@ -18,32 +60,146 @@ class Recorder {
return $this.GetType().Name return $this.GetType().Name
} }
[single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
}
[void] Setter ($param, $val) {
if ($val -is [Boolean]) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 })
}
else {
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
}
}
hidden $_loop = $($this | Add-Member ScriptProperty 'loop' ` hidden $_loop = $($this | Add-Member ScriptProperty 'loop' `
{ {
return Write-Warning ("ERROR: $($this.identifier()).mode.loop is write only") [bool]$this.mode.loop
} ` } `
{ {
param([bool]$arg) param($arg)
$this._loop = $this.Setter('mode.loop', $arg) $this.mode.loop = $arg
}
)
hidden $_samplerate = $($this | Add-Member ScriptProperty 'samplerate' `
{
$this.Getter('samplerate')
} `
{
param([int]$arg)
$opts = @(22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
if ($opts.Contains($arg)) {
$this._samplerate = $this.Setter('samplerate', $arg)
}
else {
"samplerate got: $arg, expected one of $opts" | Write-Warning
}
}
)
hidden $_bitresolution = $($this | Add-Member ScriptProperty 'bitresolution' `
{
$this.Getter('bitresolution')
} `
{
param([int]$arg)
$opts = @(8, 16, 24, 32)
if ($opts.Contains($arg)) {
$this._bitresolution = $this.Setter('bitresolution', $arg)
}
else {
"bitresolution got: $arg, expected one of $opts" | Write-Warning
}
}
)
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
{
$this.Getter('channel')
} `
{
param([int]$arg)
if ($arg -ge 1 -and $arg -le 8) {
$this._channel = $this.Setter('channel', $arg)
}
else {
"channel got: $arg, expected value from 1 to 8" | Write-Warning
}
}
)
hidden $_kbps = $($this | Add-Member ScriptProperty 'kbps' `
{
$this.Getter('kbps')
} `
{
param([int]$arg)
$opts = @(32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
if ($opts.Contains($arg)) {
$this._kbps = $this.Setter('kbps', $arg)
}
else {
"kbps got: $arg, expected one of $opts" | Write-Warning
}
} }
) )
[void] Load ([string]$filename) { [void] Load ([string]$filename) {
$this.Setter('load', $filename) $this.Setter('load', $filename)
} }
[void] GoTo ([string]$timestring) {
try {
if ([datetime]::ParseExact($timestring, "HH:mm:ss", $null)) {
$timespan = [timespan]::Parse($timestring)
$this.Setter("GoTo", $timespan.TotalSeconds)
}
}
catch [FormatException] {
"Time string $timestring does not match the required format 'hh:mm:ss'" | Write-Warning
}
}
[void] FileType($format) {
[int]$val = 0
switch ($format) {
"wav" { $val = 1 }
"aiff" { $val = 2 }
"bwf" { $val = 3 }
"mp3" { $val = 100 }
default { "Filetype() got: $format, expected one of 'wav', 'aiff', 'bwf', 'mp3'" }
}
$this.Setter("filetype", $val)
}
}
class RecorderMode : IRecorder {
RecorderMode ([Object]$remote) : base ($remote) {
AddBoolMembers -PARAMS @('recbus', 'playonload', 'loop', 'multitrack')
}
[string] identifier () {
return "Recorder.Mode"
}
}
class RecorderArm : IRecorder {
[int]$index
RecorderArm ([int]$index, [Object]$remote) : base ($remote) {
$this.index = $index
}
Set ([bool]$val) {
$this.Setter("", $(if ($val) { 1 } else { 0 }))
}
}
class RecorderArmStrip : RecorderArm {
RecorderArmStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
}
[string] identifier () {
return "Recorder.ArmStrip[$($this.index)]"
}
}
class RecorderArmBus : RecorderArm {
RecorderArmBus ([int]$index, [Object]$remote) : base ($index, $remote) {
}
[string] identifier () {
return "Recorder.ArmBus[$($this.index)]"
}
} }
function Make_Recorder ([Object]$remote) { function Make_Recorder ([Object]$remote) {

View File

@@ -14,19 +14,21 @@ class IStrip {
} }
[single] Getter ($param) { [single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false return $this.remote.Getter("$($this.identifier()).$param")
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true return $this.remote.Getter_String("$($this.identifier()).$param")
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $val $this.remote.Setter("$($this.identifier()).$param", $val)
} }
} }
class Strip : IStrip { class Strip : IStrip {
[Object]$levels
Strip ([int]$index, [Object]$remote) : base ($index, $remote) { Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('mono', 'solo', 'mute') AddBoolMembers -PARAMS @('mono', 'solo', 'mute')
AddIntMembers -PARAMS @('limit') AddIntMembers -PARAMS @('limit')
@@ -35,6 +37,8 @@ class Strip : IStrip {
AddChannelMembers AddChannelMembers
AddGainlayerMembers AddGainlayerMembers
$this.levels = [StripLevels]::new($index, $remote)
} }
[string] ToString() { [string] ToString() {
@@ -50,6 +54,52 @@ class Strip : IStrip {
} }
} }
class StripLevels : IStrip {
[int]$init
[int]$offset
StripLevels ([int]$index, [Object]$remote) : base ($index, $remote) {
$p_in = $remote.kind.p_in
if ($index -lt $p_in) {
$this.init = $index * 2
$this.offset = 2
}
else {
$this.init = ($p_in * 2) + (($index - $p_in) * 8)
$this.offset = 8
}
}
[float] Convert([float]$val) {
if ($val -gt 0) {
return [math]::Round(20 * [math]::Log10($val), 1)
}
else {
return -200.0
}
}
[System.Collections.ArrayList] Getter([int]$mode) {
[System.Collections.ArrayList]$vals = @()
$this.init..$($this.init + $this.offset - 1) | ForEach-Object {
$vals.Add($this.Convert($(Get_Level -MODE $mode -INDEX $_)))
}
return $vals
}
[System.Collections.ArrayList] PreFader() {
return $this.Getter(0)
}
[System.Collections.ArrayList] PostFader() {
return $this.Getter(1)
}
[System.Collections.ArrayList] PostMute() {
return $this.Getter(2)
}
}
class PhysicalStrip : Strip { class PhysicalStrip : Strip {
[Object]$comp [Object]$comp
[Object]$gate [Object]$gate
@@ -62,16 +112,16 @@ class PhysicalStrip : Strip {
AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2') AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2')
AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2') AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2')
$this.comp = [Comp]::new($index, $remote) $this.comp = [StripComp]::new($index, $remote)
$this.gate = [Gate]::new($index, $remote) $this.gate = [StripGate]::new($index, $remote)
$this.denoiser = [Denoiser]::new($index, $remote) $this.denoiser = [StripDenoiser]::new($index, $remote)
$this.eq = [Eq]::new($index, $remote) $this.eq = [StripEq]::new($index, $remote)
$this.device = [Device]::new($index, $remote) $this.device = [StripDevice]::new($index, $remote)
} }
} }
class Comp : IStrip { class StripComp : IStrip {
Comp ([int]$index, [Object]$remote) : base ($index, $remote) { StripComp ([int]$index, [Object]$remote) : base ($index, $remote) {
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout') AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
AddBoolMembers -PARAMS @('makeup') AddBoolMembers -PARAMS @('makeup')
} }
@@ -91,8 +141,8 @@ class Comp : IStrip {
) )
} }
class Gate : IStrip { class StripGate : IStrip {
Gate ([int]$index, [Object]$remote) : base ($index, $remote) { StripGate ([int]$index, [Object]$remote) : base ($index, $remote) {
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release') AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
} }
@@ -111,8 +161,8 @@ class Gate : IStrip {
) )
} }
class Denoiser : IStrip { class StripDenoiser : IStrip {
Denoiser ([int]$index, [Object]$remote) : base ($index, $remote) { StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
} }
[string] identifier () { [string] identifier () {
@@ -130,8 +180,8 @@ class Denoiser : IStrip {
) )
} }
class Eq : IStrip { class StripEq : IStrip {
Eq ([int]$index, [Object]$remote) : base ($index, $remote) { StripEq ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('on', 'ab') AddBoolMembers -PARAMS @('on', 'ab')
} }
@@ -140,15 +190,15 @@ class Eq : IStrip {
} }
} }
class Device : IStrip { class StripDevice : IStrip {
Device ([int]$index, [Object]$remote) : base ($index, $remote) { StripDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
} }
[string] identifier () { [string] identifier () {
return "Strip[" + $this.index + "].Device" return "Strip[" + $this.index + "].Device"
} }
hidden $_device = $($this | Add-Member ScriptProperty 'device' ` hidden $_name = $($this | Add-Member ScriptProperty 'name' `
{ {
$this.Getter_String('name') $this.Getter_String('name')
} ` } `

View File

@@ -1,9 +1,11 @@
class IVban { class IVban {
[int32]$index [int32]$index
[Object]$remote
[string]$direction [string]$direction
IVban ([int]$index, [string]$direction) { IVban ([int]$index, [Object]$remote, [string]$direction) {
$this.index = $index $this.index = $index
$this.remote = $remote
$this.direction = $direction $this.direction = $direction
} }
@@ -16,20 +18,20 @@ class IVban {
} }
[single] Getter ($param) { [single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false return $this.remote.Getter("$($this.identifier()).$param")
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true return $this.remote.Getter_String("$($this.identifier()).$param")
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $val $this.remote.Setter("$($this.identifier()).$param", $val)
} }
} }
class Vban : IVban { class Vban : IVban {
Vban ([int]$index, [string]$direction) : base ($index, $direction) { Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
} }
hidden $_on = $($this | Add-Member ScriptProperty 'on' ` hidden $_on = $($this | Add-Member ScriptProperty 'on' `
@@ -68,7 +70,7 @@ class Vban : IVban {
} ` } `
{ {
param([string]$arg) param([string]$arg)
if ($arg -in 1024..65535) { if ($arg -ge 1024 -and $arg -le 65535) {
$this._port = $this.Setter('port', $arg) $this._port = $this.Setter('port', $arg)
} }
else { else {
@@ -104,7 +106,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 -in 1..8) { if ($arg -ge 1 -and $arg -le 8) {
$this._channel = $this.Setter('channel', $arg) $this._channel = $this.Setter('channel', $arg)
} }
else { else {
@@ -142,7 +144,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 -in 0..4) { if ($arg -ge 0 -and $arg -le 4) {
$this._quality = $this.Setter('quality', $arg) $this._quality = $this.Setter('quality', $arg)
} }
else { else {
@@ -160,7 +162,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 -in 0..8) { if ($arg -ge 0 -and $arg -le 8) {
$this._route = $this.Setter('route', $arg) $this._route = $this.Setter('route', $arg)
} }
else { else {
@@ -173,13 +175,13 @@ class Vban : IVban {
class VbanInstream : Vban { class VbanInstream : Vban {
VbanInstream ([int]$index, [string]$direction) : base ($index, $direction) { VbanInstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
} }
} }
class VbanOutstream : Vban { class VbanOutstream : Vban {
VbanOutstream ([int]$index, [string]$direction) : base ($index, $direction) { VbanOutstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
} }
} }
@@ -189,10 +191,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($_, "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($_, "out")) [void]$outstream.Add([VbanOutstream]::new($_, $remote, "out"))
} }
$CustomObject = [pscustomobject]@{ $CustomObject = [pscustomobject]@{

View File

@@ -34,6 +34,7 @@ Function ParseLog {
function main() { function main() {
try { try {
$vmr = Connect-Voicemeeter -Kind $kind $vmr = Connect-Voicemeeter -Kind $kind
$vmr.command.RunMacrobuttons() # ensure macrobuttons is running before we begin
Write-Host "Running tests for $vmr" Write-Host "Running tests for $vmr"
# test boundaries by kind # test boundaries by kind
@@ -72,5 +73,4 @@ function main() {
} }
main
if ($MyInvocation.InvocationName -ne '.') { main }