Compare commits

..

No commits in common. "108731b4cfdcce2fac6f0b24deb9dc7e4d788dfa" and "ff1bd5e6cc18b59caa37b67dc4cb6ddead8797cf" have entirely different histories.

18 changed files with 256 additions and 295 deletions

14
.vscode/launch.json vendored
View File

@ -16,9 +16,7 @@
"\"!strip[0].mute\",", "\"!strip[0].mute\",",
"\"strip[0].mute\",", "\"strip[0].mute\",",
"\"bus[2].eq.on=1\",", "\"bus[2].eq.on=1\",",
"\"command.lock=1\"", "\"command.lock=1\""
"-Verbose",
"-Debug"
], ],
"createTemporaryIntegratedConsole": true "createTemporaryIntegratedConsole": true
}, },
@ -28,10 +26,7 @@
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}/examples/nextbus", "cwd": "${workspaceRoot}/examples/nextbus",
"script": "${workspaceFolder}/examples/nextbus/GoTo-NextBus.ps1", "script": "${workspaceFolder}/examples/nextbus/GoTo-NextBus.ps1",
"args": [ "args": [],
"-Verbose",
"-Debug"
],
"createTemporaryIntegratedConsole": true "createTemporaryIntegratedConsole": true
}, },
{ {
@ -40,10 +35,7 @@
"request": "launch", "request": "launch",
"cwd": "${workspaceRoot}/examples/obs", "cwd": "${workspaceRoot}/examples/obs",
"script": "${workspaceFolder}/examples/obs/Vm-Obs-Sync.ps1", "script": "${workspaceFolder}/examples/obs/Vm-Obs-Sync.ps1",
"args": [ "args": [],
"-Verbose",
"-Debug"
],
"createTemporaryIntegratedConsole": true "createTemporaryIntegratedConsole": true
}, },
{ {

View File

@ -9,20 +9,7 @@ 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
## [3.2.0] - []
### Added
- Debug statements added to Getters, Setters in higher classes.
- RunVoicemeeter function added to base.ps1. Accepts kind name as parameter.
- Errors section to README.
### Fixed
- All CAPIErrors are now exposed to the consumer.
- The function name and error code can be retrieved using [CAPIError].function and [CAPIError].code
- Set_By_Script now throws [VMError] if script length exceeds 48kB.
- parameter range checks in Vban class.
## [3.1.0] ## [3.1.0]
@ -31,7 +18,6 @@ Before any major/minor/patch is released all test units will be run to verify th
- Level methods for Strip class implemented. See Strip.levels section in README. - Level methods for Strip class implemented. See Strip.levels section in README.
- Level methods for Bus class implemented. See Bus.levels section in README. - Level methods for Bus class implemented. See Bus.levels section in README.
- More Recorder commands implemented. See Recorder section in README. - More Recorder commands implemented. See Recorder section in README.
- RunMacrobuttons, CloseMacrobuttons added to Special class
## [3.0.0] ## [3.0.0]

View File

@ -115,13 +115,13 @@ $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
- label: string - label: string
@ -135,10 +135,10 @@ The following strip commands are available:
- color_y: float, from 0.0 to 1.0 - color_y: float, from 0.0 to 1.0
- fx_x: float, from -0.5 to 0.5 - fx_x: float, from -0.5 to 0.5
- fx_y: float, from 0.0 to 1.0 - fx_y: float, from 0.0 to 1.0
- postreverb: bool - postreverb: boolean
- postdelay: bool - postdelay: boolean
- postfx1: bool - postfx1: boolean
- postfx2: bool - postfx2: boolean
- gainlayer0-gainlayer7: float - gainlayer0-gainlayer7: float
for example: for example:
@ -165,7 +165,7 @@ The following strip.comp commands are available:
- release: float, from 0.0 to 5000.0 - release: float, from 0.0 to 5000.0
- knee: float, 0.0 to 1.0 - knee: float, 0.0 to 1.0
- gainout: float, from -24.0 to 24.0 - gainout: float, from -24.0 to 24.0
- makeup: bool - makeup: boolean
for example: for example:
@ -206,7 +206,7 @@ $vmr.strip[3].denoiser.knob = 5
#### AppGain | AppMute #### AppGain | AppMute
- `AppGain(amount, gain)` : string, float - `AppGain(amount, gain)` : string, float
- `AppMute(amount, mutestate)` : string, bool - `AppMute(amount, mutestate)` : string, boolean
for example: for example:
@ -253,18 +253,18 @@ $vmr.bus[3].returnreverb = 5.7
The following bus.mode members are available: The following bus.mode members are available:
- normal: bool - normal: boolean
- amix: bool - amix: boolean
- bmix: bool - bmix: boolean
- repeat: bool - repeat: boolean
- composite: bool - composite: boolean
- tvmix: bool - tvmix: boolean
- upmix21: bool - upmix21: boolean
- upmix41: bool - upmix41: boolean
- upmix61: bool - upmix61: boolean
- centeronly: bool - centeronly: boolean
- lfeonly: bool - lfeonly: boolean
- rearonly: bool - rearonly: boolean
The following bus.mode commands are available: The following bus.mode commands are available:
@ -317,8 +317,8 @@ wdm, ks, mme, asio are defined as write only.
The following strip.eq | bus.eq commands are available: The following strip.eq | bus.eq commands are available:
- on: bool - on: boolean
- ab: bool - ab: boolean
for example: for example:
@ -359,19 +359,19 @@ $vmr.button[5].trigger = $true
### VBAN ### VBAN
- vmr.vban.enable: Toggle VBAN on or off. Accepts a bool value. - vmr.vban.enable: Toggle VBAN on or off. Accepts a boolean value.
For each vban in/out stream the following parameters are defined: For each vban in/out stream the following parameters are defined:
- on: bool - on: boolean
- name: string - name: string
- ip: string - ip: string
- port: int, from 1024 - 65535 - port: int from 1024 - 65535
- sr: in, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000) - sr: int (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
- channel: int from 1 to 8 - channel: int from 1 to 8
- bit: int, 16 or 24 - bit: int 16 or 24
- quality: int, from 0 to 4 - quality: int from 0 to 4
- route: int, from 0 to 8 - route: int from 0 to 8
SR, channel and bit are defined as readonly for instreams. Attempting to write SR, channel and bit are defined as readonly for instreams. Attempting to write
to those parameters will throw an error. They are read and write for outstreams. to those parameters will throw an error. They are read and write for outstreams.
@ -396,14 +396,12 @@ The following commands are available:
- hide - hide
- restart - restart
- shutdown - shutdown
- showvbanchat: bool, (write only) - showvbanchat: boolean (write only)
- lock: bool, (write only) - lock: boolean (write only)
The following methods are available: The following methods are available:
- Load($filepath): string - Load($filepath): string
- RunMacrobuttons(): Launches the macrobuttons app
- CloseMacrobuttons(): Closes the macrobuttons app
example: example:
@ -413,8 +411,6 @@ $vmr.command.show
$vmr.command.lock = $true $vmr.command.lock = $true
$vmr.command.Load("path/to/filename.xml") $vmr.command.Load("path/to/filename.xml")
$vmr.command.RunMacrobuttons()
``` ```
### Recorder ### Recorder
@ -427,12 +423,12 @@ The following commands are available:
- record - record
- ff - ff
- rew - rew
- A1 - A5: bool - A1 - A5: boolean
- B1 - B3: bool - B1 - B3: boolean
- samplerate: int, (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000) - samplerate: int (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
- bitresolution: int, (8, 16, 24, 32) - bitresolution: int (8, 16, 24, 32)
- channel: int, from 1 to 8 - channel: int from 1 to 8
- kbps: int, (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320) - kbps: int (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
The following methods are available: The following methods are available:
@ -468,7 +464,7 @@ $vmr.recorder.mode.loop = $true
The following method is available: The following method is available:
- Set($val): bool - Set($val): boolean
example: example:
@ -546,15 +542,6 @@ Access to lower level polling functions are provided with these functions:
- `$vmr.PDirty`: Returns true if a parameter has been updated. - `$vmr.PDirty`: Returns true if a parameter has been updated.
- `$vmr.MDirty`: Returns true if a macrobutton has been updated. - `$vmr.MDirty`: Returns true if a macrobutton has been updated.
### Errors
- `VMRemoteError`: Base custom error class.
- `LoginError`: Raised when a login error occurs.
- `CAPIError`: Raised when a C-API function returns an error code.
- The following class properties are available:
- `function`: The name of the C-API function that returned the error code.
- `code`: The error code.
### Run tests ### Run tests
Run tests using .\tests\pre-commit.ps1 which accepts the following parameters: Run tests using .\tests\pre-commit.ps1 which accepts the following parameters:

View File

@ -1,12 +1,14 @@
[cmdletbinding()]
param( param(
[switch]$interactive, [switch]$interactive,
[switch]$output,
[String]$kind = "banana", [String]$kind = "banana",
[String[]]$script = @() [String[]]$script = @()
) )
Import-Module ..\..\lib\Voicemeeter.psm1 Import-Module ..\..\lib\Voicemeeter.psm1
$VerbosePreference = "Continue"
function get-value { function get-value {
param([object]$vmr, [string]$line) param([object]$vmr, [string]$line)
try { try {
@ -22,16 +24,16 @@ function msgHandler {
param([object]$vmr, [string]$line) param([object]$vmr, [string]$line)
$line + " passed to handler" | Write-Debug $line + " passed to handler" | Write-Debug
if ($line[0] -eq "!") { if ($line[0] -eq "!") {
"Toggling " + $line.substring(1) | Write-Debug if ($output) { "Toggling " + $line.substring(1) | Write-Host }
$retval = get-value -vmr $vmr -line $line.substring(1) $retval = get-value -vmr $vmr -line $line.substring(1)
$vmr.Setter($line.substring(1), 1 - $retval) $vmr.Setter($line.substring(1), 1 - $retval)
} }
elseif ($line.Contains("=")) { elseif ($line.Contains("=")) {
"Setting $line" | Write-Debug if ($output) { "Setting $line" | Write-Host }
$vmr.SendText($line) $vmr.SendText($line)
} }
else { else {
"Getting $line" | Write-Debug if ($output) { "Getting $line" | Write-Host }
$retval = get-value -vmr $vmr -line $line $retval = get-value -vmr $vmr -line $line
$line + " = " + $retval | Write-Host $line + " = " + $retval | Write-Host
} }

View File

@ -7,30 +7,27 @@
Credits go to @bobsupercow Credits go to @bobsupercow
#> #>
[cmdletbinding()]
param()
Import-Module ..\..\lib\Voicemeeter.psm1 Import-Module ..\..\lib\Voicemeeter.psm1
$VerbosePreference = "Continue"
try { try {
$vmr = Connect-Voicemeeter -Kind "potato" $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])
"Buses in selection: $($buses)"
$unmutedIndex = $null $unmutedIndex = $null
# 1) # 1)
"Cycling through bus selection to check for first unmuted Bus..." | Write-Host
foreach ($bus in $buses) { foreach ($bus in $buses) {
# 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
} }
@ -40,7 +37,7 @@ try {
# 4) # 4)
if ($null -eq $unmutedIndex) { if ($null -eq $unmutedIndex) {
$buses[0].mute = $false $buses[0].mute = $false
"Unmuting Bus $($buses[0].index)" | Write-Host "unmuting bus $($buses[0].index)" | Write-Host
} }
} }

View File

@ -1,9 +1,8 @@
[cmdletbinding()]
param()
Import-Module ..\..\lib\Voicemeeter.psm1 Import-Module ..\..\lib\Voicemeeter.psm1
Import-Module obs-powershell Import-Module obs-powershell
$VerbosePreference = "Continue"
function CurrentProgramSceneChanged { function CurrentProgramSceneChanged {
param([System.Object]$data) param([System.Object]$data)
Write-Host "Switched to scene", $data.sceneName Write-Host "Switched to scene", $data.sceneName
@ -11,15 +10,19 @@ function CurrentProgramSceneChanged {
switch ($data.sceneName) { switch ($data.sceneName) {
"START" { "START" {
$vmr.strip[0].mute = !$vmr.strip[0].mute $vmr.strip[0].mute = !$vmr.strip[0].mute
"Toggling Strip 0 mute"
} }
"BRB" { "BRB" {
$vmr.strip[0].gain = -8.3 $vmr.strip[0].gain = -8.3
"Setting Strip 0 gain to -8.3"
} }
"END" { "END" {
$vmr.strip[0].mono = $true $vmr.strip[0].mono = $true
"Setting Strip 0 mono to `$true"
} }
"LIVE" { "LIVE" {
$vmr.strip[0].color_x = 0.3 $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 }
} }

View File

@ -1,22 +1,14 @@
. $PSScriptRoot\errors.ps1
. $PSScriptRoot\meta.ps1
. $PSScriptRoot\base.ps1
. $PSScriptRoot\kinds.ps1 . $PSScriptRoot\kinds.ps1
. $PSScriptRoot\strip.ps1 . $PSScriptRoot\base.ps1
. $PSScriptRoot\bus.ps1
. $PSScriptRoot\macrobuttons.ps1
. $PSScriptRoot\vban.ps1
. $PSScriptRoot\command.ps1
. $PSScriptRoot\recorder.ps1
. $PSScriptRoot\profiles.ps1
class Remote { class Remote {
[String]$vmpath
[Hashtable]$kind [Hashtable]$kind
[Object]$profiles [Object]$profiles
Remote ([String]$kindId) { Remote ([String]$kindId) {
$this.vmpath = Setup_DLL if (!(Setup_DLL)) {
Exit -1
}
$this.kind = GetKind($kindId) $this.kind = GetKind($kindId)
$this.profiles = Get_Profiles($this.kind.name) $this.profiles = Get_Profiles($this.kind.name)
} }
@ -39,7 +31,7 @@ class Remote {
} }
[String] GetVersion() { [String] GetVersion() {
return VmVersion return Version
} }
[void] Set_Profile([String]$config) { [void] Set_Profile([String]$config) {
@ -137,6 +129,7 @@ Function Get-RemotePotato {
Function Connect-Voicemeeter { Function Connect-Voicemeeter {
param([String]$Kind) param([String]$Kind)
try {
switch ($Kind) { switch ($Kind) {
"basic" { "basic" {
return Get-RemoteBasic return Get-RemoteBasic
@ -147,10 +140,13 @@ Function Connect-Voicemeeter {
"potato" { "potato" {
return Get-RemotePotato return Get-RemotePotato
} }
default { default { throw [LoginError]::new("Unknown Voicemeeter kind `"$Kind`"") }
throw [LoginError]::new("Unknown Voicemeeter kind `"$Kind`"")
} }
} }
catch [LoginError], [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
throw
}
} }
Function Disconnect-Voicemeeter { Function Disconnect-Voicemeeter {

View File

@ -1,77 +1,74 @@
. $PSScriptRoot\errors.ps1 . $PSScriptRoot\errors.ps1
. $PSScriptRoot\binding.ps1 . $PSScriptRoot\binding.ps1
. $PSScriptRoot\profiles.ps1
. $PSScriptRoot\inst.ps1
. $PSScriptRoot\strip.ps1
. $PSScriptRoot\bus.ps1
. $PSScriptRoot\macrobuttons.ps1
. $PSScriptRoot\vban.ps1
. $PSScriptRoot\command.ps1
. $PSScriptRoot\recorder.ps1
function Login { function Login {
param( param(
[string]$kindId [string]$kindId
) )
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_Login() $retval = [int][Voicemeeter.Remote]::VBVMR_Login()
if ($retval -notin @(0, 1, -2)) { if (-not $retval) {
throw [CAPIError]::new($retval, "VBVMR_Login") "LOGGED IN" | Write-Verbose
}
elseif ($retval -eq 1) {
"VM NOT RUNNING" | Write-Verbose
New-Variable -Name vmExe -Value 0
if ( $kindId -eq "basic" ) { $vmExe = 1 }
elseif ( $kindId -eq "banana" ) { $vmExe = 2 }
elseif ( $kindId -eq "potato" ) {
$vmExe = $(if ([Environment]::Is64BitOperatingSystem) { 6 } else { 3 })
} }
switch ($retval) { $retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$vmExe)
1 { if (-not $retval) {
"Voicemeeter Engine running but GUI not launched. Launching GUI now." | Write-Verbose "STARTING VOICEMEETER" | Write-Verbose
RunVoicemeeter -kindId $kindId Start-Sleep -s 1
} }
-2 { else {
throw [LoginError]::new("Login may only be called once per session.") throw [CAPIError]::new($retval, $MyInvocation.MyCommand)
} }
} }
elseif ($retval -eq -2) {
throw [LoginError]::new('login may only be called once per session')
}
else { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
}
catch [LoginError] {
Write-Warning "$($_.Exception.ErrorMessage()). Fatal error, exiting..."
exit -2
}
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 } while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
"Successfully logged into Voicemeeter [" + $(VmType).ToUpper() + "] Version " + $(VmVersion) | Write-Verbose "VERSION:[" + $(VmType).ToUpper() + "]" | Write-Verbose
} }
function Logout { function Logout {
Start-Sleep -m 100 Start-Sleep -m 20
$retval = [int][Voicemeeter.Remote]::VBVMR_Logout() $retval = [int][Voicemeeter.Remote]::VBVMR_Logout()
if ($retval -notin @(0)) { if (-not $retval) { "LOGGED OUT" | Write-Verbose }
throw [CAPIError]::new($retval, "VBVMR_Logout")
}
if ($retval -eq 0) { "Sucessfully logged out" | Write-Verbose }
}
function RunVoicemeeter {
param(
[string]$kindId
)
$kinds = @{
"basic" = 1
"banana" = 2
"potato" = $(if ([Environment]::Is64BitOperatingSystem) { 6 } else { 3 })
}
$retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$kinds[$kindId])
if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_RunVoicemeeter")
}
Start-Sleep -s 1
} }
function P_Dirty { function P_Dirty {
$retval = [Voicemeeter.Remote]::VBVMR_IsParametersDirty() [bool][Voicemeeter.Remote]::VBVMR_IsParametersDirty()
if ($retval -notin @(0, 1)) {
throw [CAPIError]::new($retval, "VBVMR_IsParametersDirty")
}
[bool]$retval
} }
function M_Dirty { function M_Dirty {
$retval = [Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty() [bool][Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty()
if ($retval -notin @(0, 1)) {
throw [CAPIError]::new($retval, "VBVMR_MacroButton_IsDirty")
}
[bool]$retval
} }
function VmType { function VmType {
New-Variable -Name ptr -Value 0 New-Variable -Name ptr -Value 0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterType([ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterType([ref]$ptr)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterType")
}
switch ($ptr) { switch ($ptr) {
1 { return "basic" } 1 { return "basic" }
2 { return "banana" } 2 { return "banana" }
@ -79,12 +76,10 @@ function VmType {
} }
} }
function VmVersion { function Version {
New-Variable -Name ptr -Value 0 New-Variable -Name ptr -Value 0
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterVersion([ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterVersion([ref]$ptr)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterVersion")
}
$v1 = ($ptr -band 0xFF000000) -shr 24 $v1 = ($ptr -band 0xFF000000) -shr 24
$v2 = ($ptr -band 0x00FF0000) -shr 16 $v2 = ($ptr -band 0x00FF0000) -shr 16
$v3 = ($ptr -band 0x0000FF00) -shr 8 $v3 = ($ptr -band 0x0000FF00) -shr 8
@ -97,22 +92,28 @@ function Param_Get {
param( param(
[string]$PARAM, [bool]$IS_STRING = $false [string]$PARAM, [bool]$IS_STRING = $false
) )
Start-Sleep -m 30 Start-Sleep -m 50
while (P_Dirty) { Start-Sleep -m 1 } while (P_Dirty) { Start-Sleep -m 1 }
if ($IS_STRING) { if ($IS_STRING) {
$BYTES = [System.Byte[]]::new(512) $BYTES = [System.Byte[]]::new(512)
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES) $retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_GetParameterStringA") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
[System.Text.Encoding]::ASCII.GetString($BYTES).Trim([char]0) [System.Text.Encoding]::ASCII.GetString($BYTES).Trim([char]0)
} }
else { else {
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_GetParameterFloat") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
[single]$ptr [single]$ptr
} }
@ -122,17 +123,17 @@ function Param_Set {
param( param(
[string]$PARAM, [Object]$VALUE [string]$PARAM, [Object]$VALUE
) )
try {
if ($VALUE -is [string]) { if ($VALUE -is [string]) {
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE)
if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_SetParameterStringA")
}
} }
else { else {
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
if ($retval -notin @(0)) {
throw [CAPIError]::new($retval, "VBVMR_SetParameterFloat")
} }
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
}
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
} }
@ -140,9 +141,12 @@ function MB_Set {
param( param(
[int64]$ID, [single]$SET, [int64]$MODE [int64]$ID, [single]$SET, [int64]$MODE
) )
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE) $retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_MacroButton_SetStatus") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
} }
@ -154,9 +158,12 @@ function MB_Get {
while (M_Dirty) { Start-Sleep -m 1 } while (M_Dirty) { Start-Sleep -m 1 }
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE) $retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_MacroButton_GetStatus") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
[int]$ptr [int]$ptr
} }
@ -188,12 +195,12 @@ function Set_By_Script {
param( param(
[string]$script [string]$script
) )
if ($script.Length -gt 48000) { try {
throw [VMError]::new("Script size cannot be larger than 48kB")
}
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script) $retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_SetParameters") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
} }
@ -202,9 +209,12 @@ function Get_Level {
[int64]$MODE, [int64]$INDEX [int64]$MODE, [int64]$INDEX
) )
New-Variable -Name ptr -Value 0.0 New-Variable -Name ptr -Value 0.0
try {
$retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr) $retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr)
if ($retval -notin @(0)) { if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
throw [CAPIError]::new($retval, "VBVMR_GetLevel") }
catch [CAPIError] {
Write-Warning $_.Exception.ErrorMessage()
} }
[float]$ptr [float]$ptr
} }

View File

@ -1,11 +1,18 @@
. $PSScriptRoot\inst.ps1
function Setup_DLL { function Setup_DLL {
$VMPATH = Get_VMPath try {
$vb_path = Get_VMPath
$dll = Join-Path -Path $VMPATH -ChildPath ("VoicemeeterRemote" + ` if ([string]::IsNullOrWhiteSpace($vb_path)) {
throw [VMRemoteError]::new("couldn't get Voicemeeter path")
}
$dll = Join-Path -Path $vb_path -ChildPath ("VoicemeeterRemote" + `
(& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + ` (& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + `
".dll") ".dll")
}
catch [VMRemoteError] {
Write-Warning $_.Exception.ErrorMessage()
return $false
}
$Signature = @" $Signature = @"
[DllImport(@"$dll")] [DllImport(@"$dll")]
@ -46,5 +53,5 @@ function Setup_DLL {
"@ "@
Add-Type -MemberDefinition $Signature -Name Remote -Namespace Voicemeeter -PassThru | Out-Null Add-Type -MemberDefinition $Signature -Name Remote -Namespace Voicemeeter -PassThru | Out-Null
return $VMPATH return $true
} }

View File

@ -1,3 +1,5 @@
. $PSScriptRoot\meta.ps1
class IBus { class IBus {
[int]$index [int]$index
[Object]$remote [Object]$remote
@ -11,26 +13,20 @@ class IBus {
return "Bus[" + $this.index + "]" return "Bus[" + $this.index + "]"
} }
[string] ToString() {
return $this.GetType().Name + $this.index
}
[single] Getter ($param) { [single] Getter ($param) {
$this.ToString() + " Getter: $($this.Cmd($param))" | Write-Debug return $this.remote.Getter("$($this.identifier()).$param")
return $this.remote.Getter($this.Cmd($param))
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
$this.ToString() + " Getter_String: $($this.Cmd($param))" | Write-Debug return $this.remote.Getter_String("$($this.identifier()).$param")
return $this.remote.Getter_String($this.Cmd($param))
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
$this.ToString() + " Setter: $($this.Cmd($param))=$val" | Write-Debug $this.remote.Setter("$($this.identifier()).$param", $val)
$this.remote.Setter($this.Cmd($param), $val)
}
[string] Cmd ($param) {
if ([string]::IsNullOrEmpty($param)) {
return $this.identifier()
}
return "$($this.identifier()).$param"
} }
} }
@ -49,10 +45,6 @@ class Bus : IBus {
$this.levels = [BusLevels]::new($index, $remote) $this.levels = [BusLevels]::new($index, $remote)
} }
[string] ToString() {
return $this.GetType().Name + $this.index
}
[void] FadeTo ([single]$target, [int]$time) { [void] FadeTo ([single]$target, [int]$time) {
$this.Setter('FadeTo', "($target, $time)") $this.Setter('FadeTo', "($target, $time)")
} }

View File

@ -1,3 +1,6 @@
. $PSScriptRoot\meta.ps1
. $PSScriptRoot\inst.ps1
class Special { class Special {
[Object]$remote [Object]$remote
@ -29,12 +32,10 @@ class Special {
} }
[void] RunMacrobuttons() { [void] RunMacrobuttons() {
"Launching the MacroButtons app" | Write-Verbose Start-Process -FilePath $(Join-Path -Path $(Get_VMPath) -ChildPath "VoicemeeterMacroButtons.exe")
Start-Process -FilePath $(Join-Path -Path $this.remote.vmpath -ChildPath "VoicemeeterMacroButtons.exe")
} }
[void] CloseMacrobuttons() { [void] CloseMacrobuttons() {
"Closing the MacroButtons app" | Write-Verbose
Stop-Process -Name "VoicemeeterMacroButtons" Stop-Process -Name "VoicemeeterMacroButtons"
} }

View File

@ -1,19 +1,30 @@
class VMRemoteError : Exception { class VMRemoteError : Exception {
VMRemoteError ([string]$msg) : base ($msg) { [string]$msg
VMRemoteError ([string]$msg) {
$this.msg = $msg
}
[string] ErrorMessage () {
return $this.msg
} }
} }
class LoginError : VMRemoteError { class LoginError : VMRemoteError {
LoginError ([string]$msg) : base ($msg) { LoginError ([string]$msg) : base ([string]$msg) {
} }
} }
class CAPIError : VMRemoteError { class CAPIError : VMRemoteError {
[int]$code [int]$retval
[string]$function [string]$caller
CAPIError ([int]$code, [string]$function) : base ("$function returned $code") { CAPIError ([int]$retval, [string]$caller) {
$this.code = $code $this.retval = $retval
$this.function = $function $this.caller = $caller
}
[string] ErrorMessage () {
return "CAPI return value: {0} in {1}" -f $this.retval, $this.caller
} }
} }

View File

@ -1,13 +1,8 @@
function Get_VMPath { function Get_VMPath {
$REG_KEY = "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"
$VM_KEY = "\VB:Voicemeeter {17359A74-1236-5467}\" $vm_key = "\VB:Voicemeeter {17359A74-1236-5467}\"
try { return $(Get-ItemPropertyValue -Path ($reg_path + $vm_key) -Name UninstallString | Split-Path -Parent)
return $(Get-ItemPropertyValue -Path ($REG_KEY + $VM_KEY) -Name UninstallString | Split-Path -Parent)
}
catch {
throw [VMRemoteError]::new("Unable to fetch Voicemeeter path from the Registry.")
}
} }

View File

@ -1,9 +1,3 @@
enum ButtonTypes {
State = 1
StateOnly = 2
Trigger = 3
}
class MacroButton { class MacroButton {
[int32]$index [int32]$index
@ -16,42 +10,40 @@ class MacroButton {
} }
[int] Getter ($mode) { [int] Getter ($mode) {
"Button[$($this.index)].$([ButtonTypes].GetEnumName($mode))" | Write-Debug
return MB_Get -Id $this.index -Mode $mode return MB_Get -Id $this.index -Mode $mode
} }
[void] Setter ($val, $mode) { [void] Setter ($set, $mode) {
"Button[$($this.index)].$([ButtonTypes].GetEnumName($mode))=$val" | Write-Debug MB_Set -Id $this.index -SET $set -Mode $mode
MB_Set -Id $this.index -SET $val -Mode $mode
} }
hidden $_state = $($this | Add-Member ScriptProperty 'state' ` hidden $_state = $($this | Add-Member ScriptProperty 'state' `
{ {
[bool]$this.Getter([ButtonTypes]::State) [bool]$this.Getter(1)
} ` } `
{ {
param($arg) param($arg)
$this._state = $this.Setter($arg, [ButtonTypes]::State) $this._state = $this.Setter($arg, 1)
} }
) )
hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' ` hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' `
{ {
[bool]$this.Getter([ButtonTypes]::StateOnly) [bool]$this.Getter(2)
} ` } `
{ {
param($arg) param($arg)
$this._stateonly = $this.Setter($arg, [ButtonTypes]::StateOnly) $this._stateonly = $this.Setter($arg, 2)
} }
) )
hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' ` hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' `
{ {
[bool]$this.Getter([ButtonTypes]::Trigger) [bool]$this.Getter(3)
} ` } `
{ {
param($arg) param($arg)
$this._trigger = $this.Setter($arg, [ButtonTypes]::Trigger) $this._trigger = $this.Setter($arg, 3)
} }
) )
} }

View File

@ -24,9 +24,14 @@ function Set_Profile {
param( param(
[Object]$DATA, [string]$CONF [Object]$DATA, [string]$CONF
) )
try {
if ($null -eq $DATA -or -not $DATA.$CONF) { if ($null -eq $DATA -or -not $DATA.$CONF) {
throw [VMRemoteErrors]::new("No profile named '$CONF' has been loaded into memory.") throw [VMRemoteErrors]::new("No profile named $CONF was loaded")
} }
Param_Set_Multi -HASH $DATA.$CONF Param_Set_Multi -HASH $DATA.$CONF
Start-Sleep -m 1 Start-Sleep -m 1
} }
catch [VMRemoteErrors] {
Write-Warning $_.Exception.ErrorMessage()
}
}

View File

@ -1,3 +1,5 @@
. $PSScriptRoot\meta.ps1
class IRecorder { class IRecorder {
[Object]$remote [Object]$remote

View File

@ -1,3 +1,5 @@
. $PSScriptRoot\meta.ps1
class IStrip { class IStrip {
[int]$index [int]$index
[Object]$remote [Object]$remote
@ -12,25 +14,15 @@ class IStrip {
} }
[single] Getter ($param) { [single] Getter ($param) {
$this.Cmd($param) | Write-Debug return $this.remote.Getter("$($this.identifier()).$param")
return $this.remote.Getter($this.Cmd($param))
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
$this.Cmd($param) | Write-Debug return $this.remote.Getter_String("$($this.identifier()).$param")
return $this.remote.Getter_String($this.Cmd($param))
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
"$($this.Cmd($param))=$val" | Write-Debug $this.remote.Setter("$($this.identifier()).$param", $val)
$this.remote.Setter($this.Cmd($param), $val)
}
[string] Cmd ($param) {
if ([string]::IsNullOrEmpty($param)) {
return $this.identifier()
}
return "$($this.identifier()).$param"
} }
} }

View File

@ -13,25 +13,20 @@ class IVban {
return "vban." + $this.direction + "stream[" + $this.index + "]" return "vban." + $this.direction + "stream[" + $this.index + "]"
} }
[string] ToString() {
return $this.GetType().Name + $this.index
}
[single] Getter ($param) { [single] Getter ($param) {
return $this.remote.Getter($this.Cmd($param)) return $this.remote.Getter("$($this.identifier()).$param")
} }
[string] Getter_String ($param) { [string] Getter_String ($param) {
$this.Cmd($param) | Write-Debug return $this.remote.Getter_String("$($this.identifier()).$param")
return $this.remote.Getter_String($this.Cmd($param))
} }
[void] Setter ($param, $val) { [void] Setter ($param, $val) {
"$($this.Cmd($param))=$val" | Write-Debug $this.remote.Setter("$($this.identifier()).$param", $val)
$this.remote.Setter($this.Cmd($param), $val)
}
[string] Cmd ($param) {
if ([string]::IsNullOrEmpty($param)) {
return $this.identifier()
}
return "$($this.identifier()).$param"
} }
} }
@ -39,10 +34,6 @@ class Vban : IVban {
Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) { Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
} }
[string] ToString() {
return $this.GetType().Name + $this.index
}
hidden $_on = $($this | Add-Member ScriptProperty 'on' ` hidden $_on = $($this | Add-Member ScriptProperty 'on' `
{ {
$this.Getter('on') $this.Getter('on')