37 Commits

Author SHA1 Message Date
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
d48104c4a9 edit changelog 2022-12-18 17:03:47 +00:00
dfebb20c6e add remote sublcasses to changelog 2022-12-18 16:56:47 +00:00
150301c271 add Login() to Remote class.
method chain it in factory functions.
2022-12-18 16:48:28 +00:00
828a9a5731 minor changes. 2022-12-18 04:30:51 +00:00
3b1e469d2d Login refactor.
Return Exit value -2 for multiple login attempts.
2022-12-18 04:29:41 +00:00
3b1bb06c7d Classes for each remote kind added.
They subclass Remote.

Factory functions now return the Remote class of a Kind.

Return Exit value -1 for DLL setup error.
2022-12-18 04:27:55 +00:00
7e1c5616db fix output string 2022-12-17 20:16:02 +00:00
ff4391c6fb add entry/exit functions to readme.
rethrow LoginError exceptions, let the consumer handle it.
2022-12-17 20:10:53 +00:00
3b4185c251 update bus mode tests 2022-12-17 19:33:32 +00:00
deb3da15ea remove constructor annotations 2022-12-17 17:47:42 +00:00
408218ea32 typo fixes 2022-12-17 17:47:27 +00:00
5d1fc9736e md fixes 2022-12-17 17:19:01 +00:00
fed7489ac2 readme, changelog updated 2022-12-17 15:41:18 +00:00
cd7508b823 minor rework 2022-12-17 15:41:02 +00:00
6468270fd0 wdm, ks, mme and asio added to strip.device 2022-12-17 15:40:29 +00:00
42b17a7239 mode class added to Bus.
removed busmodemember meta functions.
2022-12-17 15:40:07 +00:00
714d761af2 update changelog 2022-12-17 02:13:17 +00:00
bb94e9d4e5 update tests to reflect v3 changes 2022-12-17 02:12:32 +00:00
72467a611b enable verbose output in examples
fix host key in obs example readme.
2022-12-17 02:11:00 +00:00
e01d4f134a comp, gate, denoiser, eq, device sections added
appgain|appmute added.

todo. add examples
2022-12-16 19:41:33 +00:00
9074e0d416 add note to close OBS to end script 2022-12-16 18:57:26 +00:00
bc3216bee7 Merge branch 'dev' into add-comp-gate-eq-device 2022-12-16 18:51:00 +00:00
2a476b8ffe start constructing version 3 section in changelog
add to todo list.
2022-12-16 18:41:22 +00:00
fc290ba90c entry/exit functions added 2022-12-16 18:19:35 +00:00
a40e36998c meta functions refactored to use class identifiers 2022-12-16 17:40:47 +00:00
c37b4e0b1b IVban class added
getters/setters moved into IVban

refactored to use identifier()
2022-12-16 17:30:06 +00:00
14c8a54f01 refactored to use identifier() 2022-12-16 17:29:04 +00:00
a642dfd154 getters now return boolean values 2022-12-16 17:27:58 +00:00
ec296059d4 refactored to use identifier() 2022-12-16 17:27:05 +00:00
c999e73e14 IStrip class added.
getters/setters moved into IStrip

Comp, Gate, Denoiser, Eq and Device classes added to PhysicalStrip

AppGain, AppMute methods added to VirtualStrip
2022-12-16 17:24:31 +00:00
d86ad2fe87 IBus class added.
getters/setters moved into IBus

Eq class added to Bus

Device class added to PhysicalBus
2022-12-16 17:18:51 +00:00
62ad51c6b8 examples now using relative import path
obs example now using obs-powershell module. README updated.
2022-12-16 17:16:02 +00:00
20 changed files with 1116 additions and 482 deletions

View File

@@ -9,8 +9,45 @@ 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.
- [ ] Implement comp/gate parameters introduced in v3.0.2.8 of the api.
## [3.0.0]
v3 introduces some breaking changes. They are as follows:
- Strip[i].comp now references [Comp] class. (see README for details on settings strip.comp parameters)
- Strip[i].gate now references [Gate] class. (see README for details on settings strip.gate parameters)
- Strip[i].eq now references [Eq] class. (see README for details on settings strip.eq parameters)
- Strip[i].device now references [Device] class. (see README for details on settings strip.device parameters)
- Bus[i].eq now references [Eq] class. (see README for details on settings bus.eq parameters)
- Bus[i].mode now implemented as its own class [Mode]. (see README for details on settings bus.mode parameters)
There are other changes but they should not be breaking.
### Changed
- meta functions refactored, they now use identifier() functions.
- OBS example reworked, now using obs-powershell module.
- Rethrow LoginError for unknown kind exceptions, let the consumer handle it from there.
### Added
- Entry/exit points Connect-Voicemeeter, Disconnect-Voicemeeter added to module.
- Comp, Gate, Denoiser and Eq classes added to PhysicalStrip
- Device class added to PhysicalStrip/PhysicalBus
- AppGain(), AppMute() methods added to VirtualStrip
- eq added to Bus
- interface classes IBus, IStrip and IVban added. getters/setters moved into interface classes.
- RemoteBasic, RemoteBanana and RemotePotato subclasses added.
### Fixed
- Button getters return boolean values.
### Removed
- Bus[i].mode\_{param} members removed. Replaced with Bus[i].mode.{param}
## [2.5.0] - 2022-10-27 ## [2.5.0] - 2022-10-27

200
README.md
View File

@@ -79,6 +79,21 @@ 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:
- Connect-Voicemeeter
- Disconnect-Voicemeeter
`Connect-Voicemeeter` takes a single parameter `Kind`.
for example:
```powershell
$vmr = Connect-Voicemeeter -Kind "potato"
...
Disconnect-Voicemeeter
```
#### `Through the Shell` #### `Through the Shell`
One liners should be run through a subshell, you may pipe the Remote object to a script block, for example: One liners should be run through a subshell, you may pipe the Remote object to a script block, for example:
@@ -100,20 +115,16 @@ $vmr.Logout()
The following strip commands are available: The following strip commands are available:
- mute: bool - mute: boolean
- mono: bool - mono: boolean
- mc: bool - mc: boolean
- k: int, from 0 to 4 - k: int, from 0 to 4
- solo: bool - solo: boolean
- A1-A5: bool - A1-A5: boolean
- B1-B3: bool - B1-B3: boolean
- limit: int, from -40 to 12 - limit: int, from -40 to 12
- gain: float, from -60.0 to 12.0 - gain: float, from -60.0 to 12.0
- comp: float, from 0.0 to 10.0
- gate: float, from 0.0 to 10.0
- label: string - label: string
- device: string
- sr: int
- reverb: float, from 0.0 to 10.0 - reverb: float, from 0.0 to 10.0
- delay: float, from 0.0 to 10.0 - delay: float, from 0.0 to 10.0
- fx1: float, from 0.0 to 10.0 - fx1: float, from 0.0 to 10.0
@@ -132,7 +143,7 @@ The following strip commands are available:
for example: for example:
``` ```powershell
$vmr.strip[5].gainlayer1 = -8.3 $vmr.strip[5].gainlayer1 = -8.3
``` ```
@@ -142,35 +153,182 @@ gainlayers defined for Potato version only.
mc, k for virtual strips only. mc, k for virtual strips only.
#### comp
The following strip.comp commands are available:
- knob: float, from 0.0 to 10.0
- gainin: float, from -24.0 to 24.0
- ratio: float, from 1.0 to 8.0
- threshold: float, from -40.0 to -3.0
- attack: float, from 0.0 to 200.0
- release: float, from 0.0 to 5000.0
- knee: float, 0.0 to 1.0
- gainout: float, from -24.0 to 24.0
- makeup: boolean
for example:
```powershell
$vmr.strip[3].comp.attack = 8.5
```
#### gate
The following strip.gate commands are available:
- knob: float, from 0.0 to 10.0
- threshold: float, from -60.0 to -10.0
- damping: float, from -60.0 to -10.0
- bpsidechain: int, from 100 to 4000
- attack: float, from 0.0 to 1000.0
- hold: float, from 0.0 to 5000.0
- release: float, from 0.0 to 5000.0
for example:
```powershell
$vmr.strip[3].gate.threshold = -40.5
```
#### denoiser
The following strip.denoiser commands are available:
- knob: float, from 0.0 to 10.0
for example:
```powershell
$vmr.strip[3].denoiser.knob = 5
```
#### AppGain | AppMute
- `AppGain(amount, gain)` : string, float
- `AppMute(amount, mutestate)` : string, boolean
for example:
```powershell
$vmr.strip[5].AppGain("Spotify", 0.5)
$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:
- mute: bool - mute: bool
- mono: bool - mono: bool
- eq: bool
- eq_ab: bool
- limit: int, from -40 to 12 - limit: int, from -40 to 12
- gain: float, from -60.0 to 12.0 - gain: float, from -60.0 to 12.0
- label: string - label: string
- device: string
- sr: int
- returnreverb: float, from 0.0 to 10.0 - returnreverb: float, from 0.0 to 10.0
- returndelay: float, from 0.0 to 10.0 - returndelay: float, from 0.0 to 10.0
- returnfx1: float, from 0.0 to 10.0 - returnfx1: float, from 0.0 to 10.0
- returnfx2: float, from 0.0 to 10.0 - returnfx2: float, from 0.0 to 10.0
- mode\_: bool, any of the following:
@('normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21',
'upmix41', 'upmix61', 'centeronly', 'lfeonly', 'rearonly')
for example: for example:
```powershell
$vmr.bus[3].returnreverb = 5.7
``` ```
$vmr.bus[3].mode_repeat = $true
#### modes
The following bus.mode members are available:
- normal: boolean
- amix: boolean
- bmix: boolean
- repeat: boolean
- composite: boolean
- tvmix: boolean
- upmix21: boolean
- upmix41: boolean
- upmix61: boolean
- centeronly: boolean
- lfeonly: boolean
- rearonly: boolean
The following bus.mode commands are available:
- Get(): returns the current bus mode.
for example:
```powershell
$vmr.bus[0].mode.centeronly = $true
$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
The following strip.device | bus.device commands are available:
- name: string
- sr: int
- wdm: string
- ks: string
- mme: string
- asio: string
for example:
```powershell
$vmr.strip[0].device.wdm = "Mic|Line|Instrument 1 (Audient EVO4)"
$vmr.bus[0].device.name
```
name, sr are defined as read only.
wdm, ks, mme, asio are defined as write only.
#### eq
The following strip.eq | bus.eq commands are available:
- on: boolean
- ab: boolean
for example:
```powershell
$vmr.strip[0].eq.on = $true
$vmr.bus[0].eq.ab = $false
```
#### FadeTo | FadeBy
- `FadeTo(amount, time)` : float, int - `FadeTo(amount, time)` : float, int
- `FadeBy(amount, time)` : float, int - `FadeBy(amount, time)` : float, int
@@ -178,7 +336,7 @@ Modify gain to or by the selected amount in db over a time interval in ms.
for example: for example:
``` ```powershell
$vmr.strip[3].FadeTo(-18.7, 1000) $vmr.strip[3].FadeTo(-18.7, 1000)
$vmr.bus[0].FadeBy(-10, 500) $vmr.bus[0].FadeBy(-10, 500)
``` ```
@@ -191,7 +349,7 @@ Three modes defined: state, stateonly and trigger.
- Stateonly does not run associated scripts - Stateonly does not run associated scripts
- Index range (0, 69) - Index range (0, 69)
``` ```powershell
$vmr.button[3].state = $true $vmr.button[3].state = $true
$vmr.button[4].stateonly = $false $vmr.button[4].stateonly = $false

View File

@@ -1,11 +1,13 @@
param( param(
[switch]$interactive, [switch]$interactive,
[switch]$output, [switch]$output,
[String]$kind="banana", [String]$kind = "banana",
[String[]]$script = @() [String[]]$script = @()
) )
Import-Module Voicemeeter Import-Module ..\..\lib\Voicemeeter.psm1
$VerbosePreference = "Continue"
function get-value { function get-value {
param([object]$vmr, [string]$line) param([object]$vmr, [string]$line)
@@ -39,7 +41,7 @@ function msgHandler {
function read-hostuntilempty { function read-hostuntilempty {
param([object]$vmr) param([object]$vmr)
while (($line = Read-Host) -cne[string]::Empty) { msgHandler -vmr $vmr -line $line } while (($line = Read-Host) -cne [string]::Empty) { msgHandler -vmr $vmr -line $line }
} }
@@ -47,11 +49,7 @@ function main {
[object]$vmr [object]$vmr
try { try {
switch ($kind) { $vmr = Connect-Voicemeeter -Kind $kind
"basic" { $vmr = Get-RemoteBasic }
"banana" { $vmr = Get-RemoteBanana }
"potato" { $vmr = Get-RemotePotato }
}
if ($interactive) { if ($interactive) {
"Press <Enter> to exit" | Write-Host "Press <Enter> to exit" | Write-Host
@@ -62,7 +60,7 @@ function main {
msgHandler -vmr $vmr -line $_ msgHandler -vmr $vmr -line $_
} }
} }
finally { $vmr.Logout() } finally { Disconnect-Voicemeeter }
} }
if ($MyInvocation.InvocationName -ne '.') { main } if ($MyInvocation.InvocationName -ne '.') { main }

View File

@@ -7,26 +7,27 @@
Credits go to @bobsupercow Credits go to @bobsupercow
#> #>
Import-Module Voicemeeter Import-Module ..\..\lib\Voicemeeter.psm1
$VerbosePreference = "Continue"
try { try {
$vmr = Get-RemotePotato $vmr = Connect-Voicemeeter -Kind "potato"
$buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6]) $buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6])
$unmutedIndex = $null $unmutedIndex = $null
# 1) # 1)
$buses | ForEach-Object { foreach ($bus in $buses) {
$bus = $_
# 2) # 2)
if (-not $bus.mute) { if (-not $bus.mute) {
"bus " + $bus.index + " is unmuted... muting it" | Write-Host "bus $($bus.index) is unmuted... muting it" | Write-Host
$unmutedIndex = $buses.IndexOf($bus) $unmutedIndex = $buses.IndexOf($bus)
$bus.mute = $true $bus.mute = $true
# 3) # 3)
if ($buses[++ $unmutedIndex]) { if ($buses[++$unmutedIndex]) {
"unmuting bus " + $buses[$unmutedIndex].index | Write-Host "unmuting bus $($buses[$unmutedIndex].index)" | Write-Host
$buses[$unmutedIndex].mute = $false $buses[$unmutedIndex].mute = $false
break break
} }
@@ -34,7 +35,10 @@ try {
} }
} }
# 4) # 4)
if ($null -eq $unmutedIndex) { $buses[0].mute = $false } if ($null -eq $unmutedIndex) {
"unmuting bus " + $buses[0].index | Write-Host $buses[0].mute = $false
"unmuting bus $($buses[0].index)" | Write-Host
}
} }
finally { $vmr.Logout() } finally { Disconnect-Voicemeeter }

View File

@@ -5,16 +5,17 @@ Demonstrates how to sync Voicemeeter states with OBS scene switches.
## Requirements ## Requirements
- [OBS Studio 28+](https://obsproject.com/) - [OBS Studio 28+](https://obsproject.com/)
- [OBSWebSocket for Powershell](https://github.com/onyx-and-iris/OBSWebSocket-Powershell) - [OBS-Powershell](https://github.com/StartAutomating/obs-powershell)
## Use ## Use
This example assumes the following: This example assumes the following:
- OBS connection info saved in `config.psd1`, placed next to `Vm-Obs-Sync.ps1`: - OBS connection info saved in `config.psd1`, placed next to `Vm-Obs-Sync.ps1`:
```psd1 ```psd1
@{ @{
hostname = "localhost" host = "localhost"
port = 4455 port = 4455
password = "mystrongpassword" password = "mystrongpassword"
} }
@@ -23,3 +24,5 @@ This example assumes the following:
- OBS scenes named `START`, `BRB`, `END` and `LIVE` - OBS scenes named `START`, `BRB`, `END` and `LIVE`
Simply run the script and change current OBS scene. Simply run the script and change current OBS scene.
Closing OBS will end the script.

View File

@@ -1,26 +1,43 @@
Import-Module Voicemeeter Import-Module ..\..\lib\Voicemeeter.psm1
Import-Module OBSWebSocket Import-Module obs-powershell
$VerbosePreference = "Continue" $VerbosePreference = "Continue"
$info = @{ function CurrentProgramSceneChanged {
START = "Toggling Strip 0 mute" param([System.Object]$data)
BRB = "Setting Strip 0 gain to -8.3" Write-Host "Switched to scene", $data.sceneName
END = "Setting Strip 0 mono to `$false"
LIVE = "Setting Strip 0 color_x to 0.3"
}
function CurrentProgramSceneChanged($data) { switch ($data.sceneName) {
"Switched to scene " + $data.sceneName | Write-Host "START" {
$vmr.strip[0].mute = !$vmr.strip[0].mute
switch ($data.SceneName) { "Toggling Strip 0 mute"
"START" { $vmr.strip[0].mute = !$vmr.strip[0].mute } }
"BRB" { $vmr.strip[0].gain = -8.3 } "BRB" {
"END" { $vmr.strip[0].mono = $true } $vmr.strip[0].gain = -8.3
"LIVE" { $vmr.strip[0].color_x = 0.3 } "Setting Strip 0 gain to -8.3"
}
"END" {
$vmr.strip[0].mono = $true
"Setting Strip 0 mono to `$true"
}
"LIVE" {
$vmr.strip[0].color_x = 0.3
"Setting Strip 0 color_x to 0.3"
}
default { "Expected START, BRB, END or LIVE scene" | Write-Warning; return } default { "Expected START, BRB, END or LIVE scene" | Write-Warning; return }
} }
$info[$data.SceneName] | Write-Host }
function ExitStarted {
param([System.Object]$data)
"OBS shutdown has begun!" | Write-Host
break
}
function eventHandler($data) {
if (Get-Command $data.eventType -ErrorAction SilentlyContinue) {
& $data.eventType -data $data.eventData
}
} }
function ConnFromFile { function ConnFromFile {
@@ -29,21 +46,25 @@ function ConnFromFile {
} }
function main { function main {
try { $vmr = Connect-Voicemeeter -Kind "basic"
$vmr = Get-RemoteBasic
$conn = ConnFromFile
$r_client = Get-OBSRequest -hostname $conn.hostname -port $conn.port -pass $conn.password
$resp = $r_client.getVersion()
"obs version:" + $resp.obsVersion | Write-Host
"websocket version:" + $resp.obsWebSocketVersion | Write-Host
$e_client = Get-OBSEvent -hostname $conn.hostname -port $conn.port -pass $conn.password $conn = ConnFromFile
$callbacks = @("CurrentProgramSceneChanged", ${function:CurrentProgramSceneChanged}) $job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password
$e_client.Register($callbacks)
} finally { try {
$r_client.TearDown() while ($true) {
$e_client.TearDown() Receive-Job -Job $job | ForEach-Object {
$vmr.Logout() $data = $_.MessageData
if ($data.op -eq 5) {
eventHandler($data.d)
}
}
}
}
finally {
Disconnect-OBS
Disconnect-Voicemeeter
} }
} }

View File

@@ -3,38 +3,25 @@
class Remote { class Remote {
[Hashtable]$kind [Hashtable]$kind
[System.Collections.ArrayList]$strip
[System.Collections.ArrayList]$bus
[System.Collections.ArrayList]$button
[PSCustomObject]$vban
[Object]$command
[Object]$recorder
[Object]$profiles [Object]$profiles
# Constructor Remote ([String]$kindId) {
Remote ([String]$kind_id) {
$this.kind = GetKind($kind_id)
$this.Setup()
}
[void] Setup() {
if (!(Setup_DLL)) { if (!(Setup_DLL)) {
Exit Exit -1
} }
Login -KIND $this.kind.name $this.kind = GetKind($kindId)
$this.profiles = Get_Profiles($this.kind.name) $this.profiles = Get_Profiles($this.kind.name)
$this.strip = Make_Strips($this)
$this.bus = Make_Buses($this)
$this.button = Make_Buttons
$this.vban = Make_Vban($this)
$this.command = Make_Command
$this.recorder = Make_Recorder($this)
} }
[string] ToString() { [string] ToString() {
return "Voicemeeter " + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1) return "Voicemeeter " + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1)
} }
[Remote] Login() {
Login -kindId $this.kind.name
return $this
}
[void] Logout() { [void] Logout() {
Logout Logout
} }
@@ -76,16 +63,94 @@ class Remote {
[void] MDirty() { M_Dirty } [void] MDirty() { M_Dirty }
} }
class RemoteBasic : Remote {
[System.Collections.ArrayList]$strip
[System.Collections.ArrayList]$bus
[System.Collections.ArrayList]$button
[PSCustomObject]$vban
[Object]$command
RemoteBasic () : base ('basic') {
$this.strip = Make_Strips($this)
$this.bus = Make_Buses($this)
$this.button = Make_Buttons
$this.vban = Make_Vban($this)
$this.command = Make_Command
}
}
class RemoteBanana : Remote {
[System.Collections.ArrayList]$strip
[System.Collections.ArrayList]$bus
[System.Collections.ArrayList]$button
[PSCustomObject]$vban
[Object]$command
[Object]$recorder
RemoteBanana () : base ('banana') {
$this.strip = Make_Strips($this)
$this.bus = Make_Buses($this)
$this.button = Make_Buttons
$this.vban = Make_Vban($this)
$this.command = Make_Command
$this.recorder = Make_Recorder($this)
}
}
class RemotePotato : Remote {
[System.Collections.ArrayList]$strip
[System.Collections.ArrayList]$bus
[System.Collections.ArrayList]$button
[PSCustomObject]$vban
[Object]$command
[Object]$recorder
RemotePotato () : base ('potato') {
$this.strip = Make_Strips($this)
$this.bus = Make_Buses($this)
$this.button = Make_Buttons
$this.vban = Make_Vban($this)
$this.command = Make_Command
$this.recorder = Make_Recorder($this)
}
}
Function Get-RemoteBasic { Function Get-RemoteBasic {
return [Remote]::new('basic') [RemoteBasic]::new().Login()
} }
Function Get-RemoteBanana { Function Get-RemoteBanana {
return [Remote]::new('banana') [RemoteBanana]::new().Login()
} }
Function Get-RemotePotato { Function Get-RemotePotato {
return [Remote]::new('potato') [RemotePotato]::new().Login()
} }
Export-ModuleMember -Function Get-RemoteBasic, Get-RemoteBanana, Get-RemotePotato Function Connect-Voicemeeter {
param([String]$Kind)
try {
switch ($Kind) {
"basic" {
return Get-RemoteBasic
}
"banana" {
return Get-RemoteBanana
}
"potato" {
return Get-RemotePotato
}
default { throw [LoginError]::new("Unknown Voicemeeter kind `"$Kind`"") }
}
}
catch [LoginError], [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
throw
}
}
Function Disconnect-Voicemeeter {
Logout
}
Export-ModuleMember -Function Get-RemoteBasic, Get-RemoteBanana, Get-RemotePotato, Connect-Voicemeeter, Disconnect-Voicemeeter

View File

@@ -11,41 +11,40 @@
function Login { function Login {
param( param(
[string]$KIND = $null [string]$kindId
) )
try { try {
$retval = [int][Voicemeeter.Remote]::VBVMR_Login() $retval = [int][Voicemeeter.Remote]::VBVMR_Login()
if (-not $retval) { "LOGGED IN" | Write-Verbose } if (-not $retval) {
"LOGGED IN" | Write-Verbose
}
elseif ($retval -eq 1) { elseif ($retval -eq 1) {
"VM NOT RUNNING" | Write-Verbose "VM NOT RUNNING" | Write-Verbose
New-Variable -Name vm_exe -Value 0 New-Variable -Name vmExe -Value 0
switch ($KIND) { if ( $kindId -eq "basic" ) { $vmExe = 1 }
'basic' { $vm_exe = 1; break } elseif ( $kindId -eq "banana" ) { $vmExe = 2 }
'banana' { $vm_exe = 2; break } elseif ( $kindId -eq "potato" ) {
'potato' { $vmExe = $(if ([Environment]::Is64BitOperatingSystem) { 6 } else { 3 })
if ([Environment]::Is64BitOperatingSystem) {
$vm_exe = 6
}
else { $vm_exe = 3 }
break
}
default { throw [LoginError]::new('Unknown Voicemeeter type') }
} }
$retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$vm_exe) $retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$vmExe)
if (-not $retval) { "STARTING VOICEMEETER" | Write-Verbose } if (-not $retval) {
else { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) } "STARTING VOICEMEETER" | Write-Verbose
Start-Sleep -s 1 Start-Sleep -s 1
} }
else {
throw [CAPIError]::new($retval, $MyInvocation.MyCommand)
}
}
elseif ($retval -eq -2) { elseif ($retval -eq -2) {
throw [LoginError]::new('Login may only be called once per session') throw [LoginError]::new('login may only be called once per session')
} }
else { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) } else { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
} }
catch [LoginError], [CAPIError] { catch [LoginError] {
Write-Warning $_.Exception.ErrorMessage() Write-Warning "$($_.Exception.ErrorMessage()). Fatal error, exiting..."
exit exit -2
} }
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 } while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
@@ -204,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

@@ -3,13 +3,13 @@ function Setup_DLL {
$vb_path = Get_VBPath $vb_path = Get_VBPath
if ([string]::IsNullOrWhiteSpace($vb_path)) { if ([string]::IsNullOrWhiteSpace($vb_path)) {
throw [VMRemoteErrors]::new("ERROR: Couldn't get Voicemeeter path") throw [VMRemoteError]::new("couldn't get Voicemeeter path")
} }
$dll = Join-Path -Path $vb_path -ChildPath ("VoicemeeterRemote" + ` $dll = Join-Path -Path $vb_path -ChildPath ("VoicemeeterRemote" + `
(& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + ` (& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + `
".dll") ".dll")
} }
catch [VMRemoteErrors] { catch [VMRemoteError] {
Write-Warning $_.Exception.ErrorMessage() Write-Warning $_.Exception.ErrorMessage()
return $false return $false
} }
@@ -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

@@ -1,89 +1,197 @@
. $PSScriptRoot\meta.ps1 . $PSScriptRoot\meta.ps1
class Bus { class IBus {
[int]$index [int]$index
[Object]$remote [Object]$remote
# Constructor IBus ([int]$index, [Object]$remote) {
Bus ([int]$index, [Object]$remote) {
$this.index = $index $this.index = $index
$this.remote = $remote $this.remote = $remote
}
AddBoolMembers -PARAMS @('mono', 'mute') [string] identifier () {
AddStringMembers -PARAMS @('label') return "Bus[" + $this.index + "]"
AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
AddBusModeMembers -PARAMS @('normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21')
AddBusModeMembers -PARAMS @('upmix41', 'upmix61', 'centeronly', 'lfeonly', 'rearonly')
} }
[string] ToString() { [string] ToString() {
return $this.GetType().Name + $this.index return $this.GetType().Name + $this.index
} }
[single] Getter ($cmd) { [single] Getter ($param) {
return Param_Get -PARAM $cmd -IS_STRING $false return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
} }
[string] Getter_String ($cmd) { [string] Getter_String ($param) {
return Param_Get -PARAM $cmd -IS_STRING $true return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
} }
[void] Setter ($cmd, $set) { [void] Setter ($param, $set) {
Param_Set -PARAM $cmd -Value $set Param_Set -PARAM "$($this.identifier()).$param" -Value $set
} }
}
[string] cmd ($arg) { class Bus : IBus {
return "Bus[" + $this.index + "].$arg" [Object]$mode
} [Object]$eq
[Object]$levels
hidden $_eq = $($this | Add-Member ScriptProperty 'eq' ` Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
{ AddBoolMembers -PARAMS @('mono', 'mute')
[bool]$this.Getter($this.cmd('EQ.on')) AddStringMembers -PARAMS @('label')
} ` AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
{
param($arg)
$this._eq = $this.Setter($this.cmd('EQ.on'), $arg)
}
)
hidden $_eq_ab = $($this | Add-Member ScriptProperty 'eq_ab' ` $this.mode = [Mode]::new($index, $remote)
{ $this.eq = [Eq]::new($index, $remote)
[bool]$this.Getter($this.cmd('eq.ab')) $this.levels = [Levels]::new($index, $remote)
} `
{
param($arg)
$this._eq = $this.Setter($this.cmd('eq.ab'), $arg)
} }
)
[void] FadeTo ([single]$target, [int]$time) { [void] FadeTo ([single]$target, [int]$time) {
$this.Setter($this.cmd('FadeTo'), "($target, $time)") $this.Setter('FadeTo', "($target, $time)")
} }
[void] FadeBy ([single]$target, [int]$time) { [void] FadeBy ([single]$target, [int]$time) {
$this.Setter($this.cmd('FadeBy'), "($target, $time)") $this.Setter('FadeBy', "($target, $time)")
}
}
class Levels : IBus {
[int]$init
[int]$offset
Levels ([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 Mode : IBus {
[System.Collections.ArrayList]$modes
Mode ([int]$index, [Object]$remote) : base ($index, $remote) {
$this.modes = @(
'normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21', 'upmix41', 'upmix61',
'centeronly', 'lfeonly', 'rearonly'
)
AddBoolMembers -PARAMS $this.modes
}
[string] identifier () {
return "Bus[" + $this.index + "].mode"
}
[string] Get () {
foreach ($mode in $this.modes) {
if ($this.$mode) {
break
}
}
return $mode
}
}
class Eq : IBus {
Eq ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('on', 'ab')
}
[string] identifier () {
return "Bus[" + $this.index + "].EQ"
} }
} }
class PhysicalBus : Bus { class PhysicalBus : Bus {
[Object]$device
PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) { PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) {
$this.device = [Device]::new($index, $remote)
} }
hidden $_device = $($this | Add-Member ScriptProperty 'device' ` }
class Device : IBus {
Device ([int]$index, [Object]$remote) : base ($index, $remote) {
}
[string] identifier () {
return "Bus[" + $this.index + "].Device"
}
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
{ {
$this.Getter_String($this.cmd('device.name')) $this.Getter_String('name')
} ` } `
{ {
return Write-Warning ("ERROR: " + $this.cmd('device.name') + " is read only") return Write-Warning ("ERROR: $($this.identifier()).name is read only")
} }
) )
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' ` hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
{ {
$this.Getter($this.cmd('device.sr')) $this.Getter('sr')
} ` } `
{ {
return Write-Warning ("ERROR: " + $this.cmd('device.sr') + " is read only") return Write-Warning ("ERROR: $($this.identifier()).sr is read only")
}
)
hidden $_wdm = $($this | Add-Member ScriptProperty 'wdm' `
{
return Write-Warning ("ERROR: $($this.identifier()).wdm is write only")
} `
{
param($arg)
return $this.Setter('wdm', $arg)
}
)
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
{
return Write-Warning ("ERROR: $($this.identifier()).ks is write only")
} `
{
param($arg)
return $this.Setter('ks', $arg)
}
)
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
{
return Write-Warning ("ERROR: $($this.identifier()).mme is write only")
} `
{
param($arg)
return $this.Setter('mme', $arg)
}
)
hidden $_asio = $($this | Add-Member ScriptProperty 'asio' `
{
return Write-Warning ("ERROR: $($this.identifier()).asio is write only")
} `
{
param($arg)
return $this.Setter('asio', $arg)
} }
) )
} }

View File

@@ -1,61 +1,60 @@
. $PSScriptRoot\meta.ps1 . $PSScriptRoot\meta.ps1
class Special { class Special {
# Constructor
Special () { Special () {
AddActionMembers -PARAMS @('restart', 'shutdown', 'show') AddActionMembers -PARAMS @('restart', 'shutdown', 'show')
} }
[string] identifier () {
return "Command"
}
[string] ToString() { [string] ToString() {
return $this.GetType().Name return $this.GetType().Name
} }
[single] Getter ($cmd) { [single] Getter ($param) {
return Param_Get -PARAM $cmd -IS_STRING $false return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
if ($val -is [Boolean]) { if ($val -is [Boolean]) {
Param_Set -PARAM $param -Value $(if ($val) { 1 } else { 0 }) Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 })
} }
else { else {
Param_Set -PARAM $param -Value $val Param_Set -PARAM "$($this.identifier()).$param" -Value $val
} }
} }
[string] cmd ($arg) {
return "Command.$arg"
}
hidden $_hide = $($this | Add-Member ScriptProperty 'hide' ` hidden $_hide = $($this | Add-Member ScriptProperty 'hide' `
{ {
$this._hide = $this.Setter($this.cmd('show'), $false) $this._hide = $this.Setter('show', $false)
} ` } `
{} {}
) )
hidden $_showvbanchat = $($this | Add-Member ScriptProperty 'showvbanchat' ` hidden $_showvbanchat = $($this | Add-Member ScriptProperty 'showvbanchat' `
{ {
$this.Getter($this.cmd('DialogShow.VBANCHAT')) $this.Getter('DialogShow.VBANCHAT')
} ` } `
{ {
param([bool]$arg) param([bool]$arg)
$this._showvbanchat = $this.Setter($this.cmd('DialogShow.VBANCHAT'), $arg) $this._showvbanchat = $this.Setter('DialogShow.VBANCHAT', $arg)
} }
) )
hidden $_lock = $($this | Add-Member ScriptProperty 'lock' ` hidden $_lock = $($this | Add-Member ScriptProperty 'lock' `
{ {
$this._lock = $this.Getter($this.cmd('lock')) $this._lock = $this.Getter('lock')
} ` } `
{ {
param([bool]$arg) param([bool]$arg)
$this._lock = $this.Setter($this.cmd('lock'), $arg) $this._lock = $this.Setter('lock', $arg)
} }
) )
[void] Load ([string]$filename) { [void] Load ([string]$filename) {
$this.Setter($this.cmd('load'), $filename) $this.Setter('load', $filename)
} }
} }

View File

@@ -1,7 +1,7 @@
class VMRemoteErrors : Exception { class VMRemoteError : Exception {
[string]$msg [string]$msg
VMRemoteErrors ([string]$msg) { VMRemoteError ([string]$msg) {
$this.msg = $msg $this.msg = $msg
} }
@@ -10,12 +10,12 @@ class VMRemoteErrors : Exception {
} }
} }
class LoginError : VMRemoteErrors { class LoginError : VMRemoteError {
LoginError ([string]$msg) : base ([string]$msg) { LoginError ([string]$msg) : base ([string]$msg) {
} }
} }
class CAPIError : VMRemoteErrors { class CAPIError : VMRemoteError {
[int]$retval [int]$retval
[string]$caller [string]$caller
@@ -25,6 +25,6 @@ class CAPIError : VMRemoteErrors {
} }
[string] ErrorMessage () { [string] ErrorMessage () {
return "ERROR: CAPI return value: {0} in {1}" -f $this.retval, $this.caller return "CAPI return value: {0} in {1}" -f $this.retval, $this.caller
} }
} }

View File

@@ -28,6 +28,6 @@ $KindMap = @{
}; };
} }
function GetKind ([string]$kind_id) { function GetKind ([string]$kindId) {
$KindMap[$kind_id] $KindMap[$kindId]
} }

View File

@@ -1,7 +1,6 @@
class MacroButton { class MacroButton {
[int32]$index [int32]$index
# Constructor
MacroButton ([int]$index) { MacroButton ([int]$index) {
$this.index = $index $this.index = $index
} }
@@ -20,7 +19,7 @@ class MacroButton {
hidden $_state = $($this | Add-Member ScriptProperty 'state' ` hidden $_state = $($this | Add-Member ScriptProperty 'state' `
{ {
$this.Getter(1) [bool]$this.Getter(1)
} ` } `
{ {
param($arg) param($arg)
@@ -30,7 +29,7 @@ class MacroButton {
hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' ` hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' `
{ {
$this.Getter(2) [bool]$this.Getter(2)
} ` } `
{ {
param($arg) param($arg)
@@ -40,7 +39,7 @@ class MacroButton {
hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' ` hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' `
{ {
$this.Getter(3) [bool]$this.Getter(3)
} ` } `
{ {
param($arg) param($arg)

View File

@@ -5,9 +5,9 @@ function AddBoolMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[bool]`$this.Getter(`$this.cmd('{0}'))" -f $param $Signatures["Getter"] = "[bool]`$this.Getter('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter(`$this.cmd('{0}'), `$arg)" ` $Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@@ -21,9 +21,9 @@ function AddFloatMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[math]::Round(`$this.Getter(`$this.cmd('{0}')), 1)" -f $param $Signatures["Getter"] = "[math]::Round(`$this.Getter('{0}'), 1)" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter(`$this.cmd('{0}'), `$arg)" ` $Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@@ -37,9 +37,9 @@ function AddIntMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[Int]`$this.Getter(`$this.cmd('{0}'))" -f $param $Signatures["Getter"] = "[Int]`$this.Getter('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter(`$this.cmd('{0}'), `$arg)" ` $Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@@ -53,9 +53,9 @@ function AddStringMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "[String]`$this.Getter_String(`$this.cmd('{0}'))" -f $param $Signatures["Getter"] = "[String]`$this.Getter_String('{0}')" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "param ( [String]`$arg )`n`$this.Setter(`$this.cmd('{0}'), `$arg)" ` $Signatures["Setter"] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" `
-f $param -f $param
Addmember Addmember
@@ -69,7 +69,7 @@ function AddActionMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
foreach ($param in $PARAMS) { foreach ($param in $PARAMS) {
# Define getter # Define getter
$Signatures["Getter"] = "`$this.Setter(`$this.cmd('{0}'), `$true)" -f $param $Signatures["Getter"] = "`$this.Setter('{0}', `$true)" -f $param
# Define setter # Define setter
$Signatures["Setter"] = "" $Signatures["Setter"] = ""
@@ -93,9 +93,9 @@ function AddGainlayerMembers () {
[hashtable]$Signatures = @{} [hashtable]$Signatures = @{}
0..7 | ForEach-Object { 0..7 | ForEach-Object {
# Define getter # Define getter
$Signatures["Getter"] = "`$this.Getter(`$this.cmd('gainlayer[{0}]'))" -f $_ $Signatures["Getter"] = "`$this.Getter('gainlayer[{0}]')" -f $_
# Define setter # Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter(`$this.cmd('gainlayer[{0}]'), `$arg)" ` $Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('gainlayer[{0}]', `$arg)" `
-f $_ -f $_
$param = "gainlayer{0}" -f $_ $param = "gainlayer{0}" -f $_
$null = $param $null = $param
@@ -104,23 +104,6 @@ function AddGainlayerMembers () {
} }
} }
function AddBusModeMembers () {
param(
[String[]]$PARAMS
)
[hashtable]$Signatures = @{}
foreach ($param in $PARAMS) {
# Define getter
$Signatures["Getter"] = "[bool]`$this.Getter(`$this.cmd('mode.{0}'))" -f $param
# Define setter
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter(`$this.cmd('mode.{0}'), `$arg)" `
-f $param
$param = "mode_{0}" -f $param
Addmember
}
}
function Addmember { function Addmember {
$AddMemberParams = @{ $AddMemberParams = @{
Name = $param Name = $param

View File

@@ -2,7 +2,7 @@
class Recorder { class Recorder {
[Object]$remote [Object]$remote
# Constructor
Recorder ([Object]$remote) { Recorder ([Object]$remote) {
$this.remote = $remote $this.remote = $remote
@@ -10,39 +10,39 @@ class Recorder {
AddChannelMembers AddChannelMembers
} }
[string] identifier () {
return "Recorder"
}
[string] ToString() { [string] ToString() {
return $this.GetType().Name return $this.GetType().Name
} }
[single] Getter ($cmd) { [single] Getter ($param) {
return Param_Get -PARAM $cmd -IS_STRING $false return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
if ($val -is [Boolean]) { if ($val -is [Boolean]) {
Param_Set -PARAM $param -Value $(if ($val) { 1 } else { 0 }) Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 })
} }
else { else {
Param_Set -PARAM $param -Value $val Param_Set -PARAM "$($this.identifier()).$param" -Value $val
} }
} }
[string] cmd ($arg) {
return "Recorder.$arg"
}
hidden $_loop = $($this | Add-Member ScriptProperty 'loop' ` hidden $_loop = $($this | Add-Member ScriptProperty 'loop' `
{ {
return Write-Warning ("ERROR: " + $this.cmd('mode.loop') + " is write only") return Write-Warning ("ERROR: $($this.identifier()).mode.loop is write only")
} ` } `
{ {
param([bool]$arg) param([bool]$arg)
$this._loop = $this.Setter($this.cmd('mode.loop'), $arg) $this._loop = $this.Setter('mode.loop', $arg)
} }
) )
[void] Load ([string]$filename) { [void] Load ([string]$filename) {
$this.Setter($this.cmd('load'), $filename) $this.Setter('load', $filename)
} }
} }

View File

@@ -1,13 +1,35 @@
. $PSScriptRoot\meta.ps1 . $PSScriptRoot\meta.ps1
class Strip { class IStrip {
[int]$index [int]$index
[Object]$remote [Object]$remote
Strip ([int]$index, [Object]$remote) { IStrip ([int]$index, [Object]$remote) {
$this.index = $index $this.index = $index
$this.remote = $remote $this.remote = $remote
}
[string] identifier () {
return "Strip[" + $this.index + "]"
}
[single] Getter ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
}
[string] Getter_String ($param) {
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
}
[void] Setter ($param, $val) {
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
}
}
class Strip : IStrip {
[Object]$levels
Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('mono', 'solo', 'mute') AddBoolMembers -PARAMS @('mono', 'solo', 'mute')
AddIntMembers -PARAMS @('limit') AddIntMembers -PARAMS @('limit')
AddFloatMembers -PARAMS @('gain', 'pan_x', 'pan_y') AddFloatMembers -PARAMS @('gain', 'pan_x', 'pan_y')
@@ -15,59 +37,222 @@ class Strip {
AddChannelMembers AddChannelMembers
AddGainlayerMembers AddGainlayerMembers
$this.levels = [Levels]::new($index, $remote)
} }
[string] ToString() { [string] ToString() {
return $this.GetType().Name + $this.index return $this.GetType().Name + $this.index
} }
[single] Getter ($cmd) {
return Param_Get -PARAM $cmd -IS_STRING $false
}
[string] Getter_String ($cmd) {
return Param_Get -PARAM $cmd -IS_STRING $true
}
[void] Setter ($cmd, $val) {
Param_Set -PARAM $cmd -Value $val
}
[string] cmd ($arg) {
return "Strip[" + $this.index + "].$arg"
}
[void] FadeTo ([single]$target, [int]$time) { [void] FadeTo ([single]$target, [int]$time) {
$this.Setter($this.cmd('FadeTo'), "($target, $time)") $this.Setter('FadeTo', "($target, $time)")
} }
[void] FadeBy ([single]$target, [int]$time) { [void] FadeBy ([single]$target, [int]$time) {
$this.Setter($this.cmd('FadeBy'), "($target, $time)") $this.Setter('FadeBy', "($target, $time)")
}
}
class Levels : IStrip {
[int]$init
[int]$offset
Levels ([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]$gate
[Object]$denoiser
[Object]$eq
[Object]$device
PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) { PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
AddFloatMembers -PARAMS @('comp', 'gate', 'color_x', 'color_y', 'fx_x', 'fx_y') AddFloatMembers -PARAMS @('color_x', 'color_y', 'fx_x', 'fx_y')
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.gate = [Gate]::new($index, $remote)
$this.denoiser = [Denoiser]::new($index, $remote)
$this.eq = [Eq]::new($index, $remote)
$this.device = [Device]::new($index, $remote)
}
}
class Comp : IStrip {
Comp ([int]$index, [Object]$remote) : base ($index, $remote) {
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
AddBoolMembers -PARAMS @('makeup')
} }
hidden $_device = $($this | Add-Member ScriptProperty 'device' ` [string] identifier () {
return "Strip[" + $this.index + "].Comp"
}
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
{ {
$this.Getter_String($this.cmd('device.name')) $this.Getter_String('')
} ` } `
{ {
return Write-Warning ("ERROR: " + $this.cmd('device.name') + " is read only") param($arg)
return $this.Setter('', $arg)
}
)
}
class Gate : IStrip {
Gate ([int]$index, [Object]$remote) : base ($index, $remote) {
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
}
[string] identifier () {
return "Strip[" + $this.index + "].Gate"
}
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
{
$this.Getter_String('')
} `
{
param($arg)
return $this.Setter('', $arg)
}
)
}
class Denoiser : IStrip {
Denoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
}
[string] identifier () {
return "Strip[" + $this.index + "].Denoiser"
}
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
{
$this.Getter_String('')
} `
{
param($arg)
return $this.Setter('', $arg)
}
)
}
class Eq : IStrip {
Eq ([int]$index, [Object]$remote) : base ($index, $remote) {
AddBoolMembers -PARAMS @('on', 'ab')
}
[string] identifier () {
return "Strip[" + $this.index + "].EQ"
}
}
class Device : IStrip {
Device ([int]$index, [Object]$remote) : base ($index, $remote) {
}
[string] identifier () {
return "Strip[" + $this.index + "].Device"
}
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
{
$this.Getter_String('name')
} `
{
return Write-Warning ("ERROR: $($this.identifier()).name is read only")
} }
) )
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' ` hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
{ {
$this.Getter($this.cmd('device.sr')) $this.Getter('sr')
} ` } `
{ {
return Write-Warning ("ERROR: " + $this.cmd('device.sr') + " is read only") return Write-Warning ("ERROR: $($this.identifier()).sr is read only")
}
)
hidden $_wdm = $($this | Add-Member ScriptProperty 'wdm' `
{
return Write-Warning ("ERROR: $($this.identifier()).wdm is write only")
} `
{
param($arg)
return $this.Setter('wdm', $arg)
}
)
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
{
return Write-Warning ("ERROR: $($this.identifier()).ks is write only")
} `
{
param($arg)
return $this.Setter('ks', $arg)
}
)
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
{
return Write-Warning ("ERROR: $($this.identifier()).mme is write only")
} `
{
param($arg)
return $this.Setter('mme', $arg)
}
)
hidden $_asio = $($this | Add-Member ScriptProperty 'asio' `
{
return Write-Warning ("ERROR: $($this.identifier()).asio is write only")
} `
{
param($arg)
return $this.Setter('asio', $arg)
} }
) )
} }
@@ -77,6 +262,14 @@ class VirtualStrip : Strip {
AddBoolMembers -PARAMS @('mc') AddBoolMembers -PARAMS @('mc')
AddIntMembers -PARAMS @('k') AddIntMembers -PARAMS @('k')
} }
[void] AppGain ([string]$appname, [single]$gain) {
$this.Setter('AppGain', "(`"$appname`", $gain)")
}
[void] AppMute ([string]$appname, [bool]$mutestate) {
$this.Setter('AppMute', "(`"$appname`", $(if ($mutestate) { 1 } else { 0 })")
}
} }

View File

@@ -1,70 +1,75 @@
class Vban { class IVban {
[int32]$index [int32]$index
[string]$direction [string]$direction
# Constructor IVban ([int]$index, [string]$direction) {
Vban ([int]$index) {
$this.index = $index $this.index = $index
$this.direction = $direction
}
[string] identifier () {
return "vban." + $this.direction + "stream[" + $this.index + "]"
} }
[string] ToString() { [string] ToString() {
return $this.GetType().Name + $this.index return $this.GetType().Name + $this.index
} }
[single] Getter ($cmd) { [single] Getter ($param) {
return Param_Get -PARAM $cmd -IS_STRING $false return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
} }
[string] Getter_String ($cmd) { [string] Getter_String ($param) {
return Param_Get -PARAM $cmd -IS_STRING $true return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
} }
[void] Setter ($cmd, $set) { [void] Setter ($param, $val) {
Param_Set -PARAM $cmd -Value $set Param_Set -PARAM "$($this.identifier()).$param" -Value $val
} }
}
[string] cmd ($arg) { class Vban : IVban {
return "vban." + $this.direction + "stream[" + $this.index + "].$arg" Vban ([int]$index, [string]$direction) : base ($index, $direction) {
} }
hidden $_on = $($this | Add-Member ScriptProperty 'on' ` hidden $_on = $($this | Add-Member ScriptProperty 'on' `
{ {
$this.Getter($this.cmd('on')) $this.Getter('on')
} ` } `
{ {
param([bool]$arg) param([bool]$arg)
$this._on = $this.Setter($this.cmd('on'), $arg) $this._on = $this.Setter('on', $arg)
} }
) )
hidden $_name = $($this | Add-Member ScriptProperty 'name' ` hidden $_name = $($this | Add-Member ScriptProperty 'name' `
{ {
$this.Getter_String($this.cmd('name')) $this.Getter_String('name')
} ` } `
{ {
param([string]$arg) param([string]$arg)
$this._name = $this.Setter($this.cmd('name'), $arg) $this._name = $this.Setter('name', $arg)
} }
) )
hidden $_ip = $($this | Add-Member ScriptProperty 'ip' ` hidden $_ip = $($this | Add-Member ScriptProperty 'ip' `
{ {
$this.Getter_String($this.cmd('ip')) $this.Getter_String('ip')
} ` } `
{ {
param([string]$arg) param([string]$arg)
$this._ip = $this.Setter($this.cmd('ip'), $arg) $this._ip = $this.Setter('ip', $arg)
} }
) )
hidden $_port = $($this | Add-Member ScriptProperty 'port' ` hidden $_port = $($this | Add-Member ScriptProperty 'port' `
{ {
$this.Getter($this.cmd('port')) $this.Getter('port')
} ` } `
{ {
param([string]$arg) param([string]$arg)
if ($arg -in 1024..65535) { if ($arg -in 1024..65535) {
$this._port = $this.Setter($this.cmd('port'), $arg) $this._port = $this.Setter('port', $arg)
} }
else { else {
Write-Warning ('Expected value from 1024 to 65535') Write-Warning ('Expected value from 1024 to 65535')
@@ -74,7 +79,7 @@ class Vban {
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' ` hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
{ {
$this.Getter($this.cmd('sr')) $this.Getter('sr')
} ` } `
{ {
param([int]$arg) param([int]$arg)
@@ -82,7 +87,7 @@ class Vban {
else { else {
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) $opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
if ($opts.Contains($arg)) { if ($opts.Contains($arg)) {
$this._port = $this.Setter($this.cmd('sr'), $arg) $this._port = $this.Setter('sr', $arg)
} }
else { else {
Write-Warning ('Expected one of', $opts) Write-Warning ('Expected one of', $opts)
@@ -93,14 +98,14 @@ class Vban {
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' ` hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
{ {
$this.Getter($this.cmd('channel')) $this.Getter('channel')
} ` } `
{ {
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 -in 1..8) {
$this._channel = $this.Setter($this.cmd('channel'), $arg) $this._channel = $this.Setter('channel', $arg)
} }
else { else {
Write-Warning ('Expected value from 1 to 8') Write-Warning ('Expected value from 1 to 8')
@@ -111,7 +116,7 @@ class Vban {
hidden $_bit = $($this | Add-Member ScriptProperty 'bit' ` hidden $_bit = $($this | Add-Member ScriptProperty 'bit' `
{ {
$val = if ($this.Getter($this.cmd('bit')) -eq 1) { 16 } else { 24 } $val = if ($this.Getter('bit') -eq 1) { 16 } else { 24 }
return $val return $val
} ` } `
{ {
@@ -120,7 +125,7 @@ class Vban {
else { else {
if (@(16, 24).Contains($arg)) { if (@(16, 24).Contains($arg)) {
$val = if ($arg -eq 16) { 1 } else { 2 } $val = if ($arg -eq 16) { 1 } else { 2 }
$this._bit = $this.Setter($this.cmd('bit'), $val) $this._bit = $this.Setter('bit', $val)
} }
else { else {
Write-Warning ('Expected value 16 or 24') Write-Warning ('Expected value 16 or 24')
@@ -131,14 +136,14 @@ class Vban {
hidden $_quality = $($this | Add-Member ScriptProperty 'quality' ` hidden $_quality = $($this | Add-Member ScriptProperty 'quality' `
{ {
$this.Getter($this.cmd('quality')) $this.Getter('quality')
} ` } `
{ {
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 -in 0..4) {
$this._quality = $this.Setter($this.cmd('quality'), $arg) $this._quality = $this.Setter('quality', $arg)
} }
else { else {
Write-Warning ('Expected value from 0 to 4') Write-Warning ('Expected value from 0 to 4')
@@ -149,14 +154,14 @@ class Vban {
hidden $_route = $($this | Add-Member ScriptProperty 'route' ` hidden $_route = $($this | Add-Member ScriptProperty 'route' `
{ {
$this.Getter($this.cmd('route')) $this.Getter('route')
} ` } `
{ {
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 -in 0..8) {
$this._route = $this.Setter($this.cmd('route'), $arg) $this._route = $this.Setter('route', $arg)
} }
else { else {
Write-Warning ('Expected value from 0 to 8') Write-Warning ('Expected value from 0 to 8')
@@ -168,17 +173,13 @@ class Vban {
class VbanInstream : Vban { class VbanInstream : Vban {
# Constructor VbanInstream ([int]$index, [string]$direction) : base ($index, $direction) {
VbanInstream ([int]$index) : base ($index) {
$this.direction = "in"
} }
} }
class VbanOutstream : Vban { class VbanOutstream : Vban {
# Constructor VbanOutstream ([int]$index, [string]$direction) : base ($index, $direction) {
VbanOutstream ([int]$index) : base ($index) {
$this.direction = "out"
} }
} }
@@ -188,10 +189,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($_)) [void]$instream.Add([VbanInstream]::new($_, "in"))
} }
0..$($remote.kind.vban_out - 1) | ForEach-Object { 0..$($remote.kind.vban_out - 1) | ForEach-Object {
[void]$outstream.Add([VbanOutstream]::new($_)) [void]$outstream.Add([VbanOutstream]::new($_, "out"))
} }
$CustomObject = [pscustomobject]@{ $CustomObject = [pscustomobject]@{

View File

@@ -27,12 +27,23 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
} }
} }
Context 'physical only' -ForEach @(
@{ Index = $phys_in }
){
Context 'eq.{param}' -Skip:$ifNotPotato {
It "Should set Strip[$index].EQ.On to $value" {
$vmr.strip[$index].eq.on = $value
$vmr.strip[$index].eq.on | Should -Be $expected
}
}
}
Context 'Bus, one physical one virtual' -ForEach @( Context 'Bus, one physical one virtual' -ForEach @(
@{ Index = $phys_out }, @{ Index = $virt_out } @{ Index = $phys_out }, @{ Index = $virt_out }
){ ){
It "Should set and get Bus[$index].Eq" -Skip:$ifBasic { It "Should set and get Bus[$index].Eq.On" -Skip:$ifBasic {
$vmr.bus[$index].eq = $value $vmr.bus[$index].eq.on = $value
$vmr.bus[$index].eq | Should -Be $expected $vmr.bus[$index].eq.on | Should -Be $expected
} }
It "Should set and get Bus[$index].Mono" { It "Should set and get Bus[$index].Mono" {
@@ -40,14 +51,14 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
$vmr.bus[$index].mono | Should -Be $expected $vmr.bus[$index].mono | Should -Be $expected
} }
It "Should set and get Bus[$index].mode_amix" -Skip:$ifBasic { It "Should set and get Bus[$index].mode.amix" -Skip:$ifBasic {
$vmr.bus[$index].mode_amix = $value $vmr.bus[$index].mode.amix = $value
$vmr.bus[$index].mode_amix | Should -Be $expected $vmr.bus[$index].mode.amix | Should -Be $expected
} }
It "Should set and get Bus[$index].mode_centeronly" -Skip:$ifBasic { It "Should set and get Bus[$index].mode.centeronly" -Skip:$ifBasic {
$vmr.bus[$index].mode_centeronly = $value $vmr.bus[$index].mode.centeronly = $value
$vmr.bus[$index].mode_centeronly | Should -Be $expected $vmr.bus[$index].mode.centeronly | Should -Be $expected
} }
} }
@@ -123,13 +134,58 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
@{ Value = 8.3; Expected = 8.3 }, @{ Value = 5.1; Expected = 5.1 } @{ Value = 8.3; Expected = 8.3 }, @{ Value = 5.1; Expected = 5.1 }
){ ){
It "Should set Strip[$index].Comp to $value" { It "Should set Strip[$index].Comp to $value" {
$vmr.strip[$index].comp = $value $vmr.strip[$index].comp.knob = $value
$vmr.strip[$index].comp | Should -Be $expected $vmr.strip[$index].comp.knob | Should -Be $expected
} }
It "Should set Strip[$index].Gate to $value" { It "Should set Strip[$index].Gate to $value" {
$vmr.strip[$index].gate = $value $vmr.strip[$index].gate.knob = $value
$vmr.strip[$index].gate | Should -Be $expected $vmr.strip[$index].gate.knob | Should -Be $expected
}
}
Context 'denoiser' -Skip:$ifNotPotato -ForEach @(
@{ Value = 8.3; Expected = 8.3 }, @{ Value = 5.1; Expected = 5.1 }
){
It "Should set Strip[$index].Denoiser to $value" {
$vmr.strip[$index].denoiser.knob = $value
$vmr.strip[$index].denoiser.knob | Should -Be $expected
}
}
Context 'comp.{param}' -Skip:$ifNotPotato -ForEach @(
@{ Value = 8.3; Expected = 8.3 }, @{ Value = 5.1; Expected = 5.1 }
){
It "Should set Strip[$index].Comp.Attack to $value" {
$vmr.strip[$index].comp.attack = $value
$vmr.strip[$index].comp.attack | Should -Be $expected
}
}
Context 'comp.{param}' -Skip:$ifNotPotato -ForEach @(
@{ Value = 0.3; Expected = 0.3 }, @{ Value = 0.8; Expected = 0.8 }
){
It "Should set Strip[$index].Comp.Knee to $value" {
$vmr.strip[$index].comp.knee = $value
$vmr.strip[$index].comp.knee | Should -Be $expected
}
}
Context 'gate.{param}' -Skip:$ifNotPotato -ForEach @(
@{ Value = 103; Expected = 103 }, @{ Value = 3800; Expected = 3800 }
){
It "Should set Strip[$index].Gate.BPSidechain to $value" {
$vmr.strip[$index].gate.bpsidechain = $value
$vmr.strip[$index].gate.bpsidechain | Should -Be $expected
}
}
Context 'gate.{param}' -Skip:$ifNotPotato -ForEach @(
@{ Value = 0.3; Expected = 0.3 }, @{ Value = 5000; Expected = 5000 }
){
It "Should set Strip[$index].Gate.Hold to $value" {
$vmr.strip[$index].gate.hold = $value
$vmr.strip[$index].gate.hold | Should -Be $expected
} }
} }
} }

View File

@@ -1,4 +1,4 @@
Param([String]$tag, [Int]$num=1, [switch]$log, [string]$kind="potato") Param([String]$tag, [Int]$num = 1, [switch]$log, [string]$kind = "potato")
Import-Module .\lib\Voicemeeter.psm1 Import-Module .\lib\Voicemeeter.psm1
Function ParseLog { Function ParseLog {
@@ -15,7 +15,7 @@ Function ParseLog {
} }
ForEach ($line in ` ForEach ($line in `
$(Get-content -Path "${logfile}")) { $(Get-Content -Path "${logfile}")) {
if ($line -match $PASSED_PATTERN) { if ($line -match $PASSED_PATTERN) {
$DATA["passed"] += $Matches[1] $DATA["passed"] += $Matches[1]
} }
@@ -32,13 +32,8 @@ Function ParseLog {
function main() { function main() {
try try {
{ $vmr = Connect-Voicemeeter -Kind $kind
switch ($kind) {
"basic" { $vmr = Get-RemoteBasic }
"banana" { $vmr = Get-RemoteBanana }
"potato" { $vmr = Get-RemotePotato }
}
Write-Host "Running tests for $vmr" Write-Host "Running tests for $vmr"
# test boundaries by kind # test boundaries by kind
@@ -71,12 +66,9 @@ function main() {
} }
} }
if($log) { Parselog -logfile $logfile } if ($log) { Parselog -logfile $logfile }
}
finally
{
$vmr.Logout()
} }
finally { Disconnect-Voicemeeter }
} }