mirror of
https://github.com/onyx-and-iris/voicemeeter-api-powershell.git
synced 2026-04-08 17:03:34 +00:00
Compare commits
20 Commits
add-comp-g
...
2ad8118f2c
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ad8118f2c | |||
| bc6162cf16 | |||
| 9b3d9f2250 | |||
| 844eaeabaa | |||
| a78cdf9a99 | |||
| a40adf27be | |||
| 1397c14522 | |||
| ff1bd5e6cc | |||
| f480b637eb | |||
| 09078d382b | |||
| 598e0dd647 | |||
| 72b5ac02d3 | |||
| a031d25a41 | |||
| 4e9ff66640 | |||
| bee52b6541 | |||
| 5bda43131b | |||
| 1c9c400f12 | |||
| aee3430962 | |||
| 47fb880b91 | |||
| acc078632d |
71
.vscode/launch.json
vendored
Normal file
71
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "PowerShell: Launch CLI Example",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}/examples/cli",
|
||||
"script": "${workspaceFolder}/examples/cli/CLI.ps1",
|
||||
"args": [
|
||||
"-s",
|
||||
"\"strip[0].mute\",",
|
||||
"\"!strip[0].mute\",",
|
||||
"\"strip[0].mute\",",
|
||||
"\"bus[2].eq.on=1\",",
|
||||
"\"command.lock=1\"",
|
||||
"-Verbose",
|
||||
"-Debug"
|
||||
],
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"name": "PowerShell: Launch NextBus Example",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}/examples/nextbus",
|
||||
"script": "${workspaceFolder}/examples/nextbus/GoTo-NextBus.ps1",
|
||||
"args": [
|
||||
"-Verbose",
|
||||
"-Debug"
|
||||
],
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"name": "PowerShell: Launch OBS Example",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}/examples/obs",
|
||||
"script": "${workspaceFolder}/examples/obs/Vm-Obs-Sync.ps1",
|
||||
"args": [
|
||||
"-Verbose",
|
||||
"-Debug"
|
||||
],
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"name": "PowerShell: Run Pester Tests",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"script": "${workspaceFolder}/tests/pre-commit.ps1",
|
||||
"args": [],
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"name": "PowerShell: Launch Quick Test",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"script": "${workspaceFolder}/quick.ps1",
|
||||
"args": [
|
||||
"-Verbose",
|
||||
"-Debug"
|
||||
],
|
||||
"createTemporaryIntegratedConsole": true
|
||||
}
|
||||
]
|
||||
}
|
||||
196
CHANGELOG.md
196
CHANGELOG.md
@@ -9,224 +9,230 @@ 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
|
||||
|
||||
- [x] Implement command.load
|
||||
- [x] Implement comp/gate parameters introduced in v3.0.2.8 of the api.
|
||||
- [x] Add unit tests for new classes.
|
||||
- [x] Update README with changes to Strip/Bus classes.
|
||||
- [x] Debug statements added to Getters, Setters in higher classes.
|
||||
|
||||
## [3.1.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Level methods for Strip class implemented. See Strip.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.
|
||||
- RunMacrobuttons, CloseMacrobuttons added to Special class
|
||||
|
||||
## [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)
|
||||
- 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)
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- Button getters return boolean values.
|
||||
|
||||
### Removed
|
||||
|
||||
- Bus[i].mode\_{param} members removed. Replaced with Bus[i].mode.{param}
|
||||
- Bus[i].mode\_{param} members removed. Replaced with Bus[i].mode.{param}
|
||||
|
||||
## [2.5.0] - 2022-10-27
|
||||
|
||||
### Added
|
||||
|
||||
- xy parameters added to strip/bus
|
||||
- fx parameters added to strip/bus
|
||||
- GetType, GetVersion added to Remote class.
|
||||
- SendText implemented (set parameters by script), added to Remote class.
|
||||
- CLI example added
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- xy parameters added to strip/bus
|
||||
- fx parameters added to strip/bus
|
||||
- GetType, GetVersion added to Remote class.
|
||||
- SendText implemented (set parameters by script), added to Remote class.
|
||||
- CLI example added
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- pester tests now support all kinds.
|
||||
- GoToNextBus example refactored
|
||||
- Previous console output now written to Debug stream.
|
||||
- pester tests now support all kinds.
|
||||
- GoToNextBus example refactored
|
||||
- Previous console output now written to Debug stream.
|
||||
|
||||
### Removed
|
||||
|
||||
- setmulti, setandget and special examples.
|
||||
- setmulti, setandget and special examples.
|
||||
|
||||
## [2.4.0] - 2022-06-25
|
||||
|
||||
### Added
|
||||
|
||||
- fadeto, fadeby methods for strips/buses
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.4 added to PSGAllery
|
||||
- fadeto, fadeby methods for strips/buses
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.4 added to PSGAllery
|
||||
|
||||
### Changed
|
||||
|
||||
- Move kinds, profiles into their own modules.
|
||||
- remove global variable layout. added GetKind() to kinds.
|
||||
- link to official documentation in readme now points to SDK repo.
|
||||
- Move kinds, profiles into their own modules.
|
||||
- remove global variable layout. added GetKind() to kinds.
|
||||
- link to official documentation in readme now points to SDK repo.
|
||||
|
||||
### Fixed
|
||||
|
||||
- number of macrobuttons
|
||||
- number of macrobuttons
|
||||
|
||||
## [2.3.0] - 2022-03-08
|
||||
|
||||
### Added
|
||||
|
||||
- mc, k properties added to virtual strips.
|
||||
- gainlayer properties added to all strips
|
||||
- busmode and eq_ab properties added to all buses.
|
||||
- Added ability to load custom profiles in psd1 format.
|
||||
- Added hide command to Command class
|
||||
- Added recorder module
|
||||
- Added recorder tests to higher.tests
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.3 added to PSGAllery
|
||||
- mc, k properties added to virtual strips.
|
||||
- gainlayer properties added to all strips
|
||||
- busmode and eq_ab properties added to all buses.
|
||||
- Added ability to load custom profiles in psd1 format.
|
||||
- Added hide command to Command class
|
||||
- Added recorder module
|
||||
- Added recorder tests to higher.tests
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.3 added to PSGAllery
|
||||
|
||||
### Changed
|
||||
|
||||
- Pester tests refactored
|
||||
- Pester tests refactored
|
||||
|
||||
### Fixed
|
||||
|
||||
- eq, eq_ab getters now return boolean values
|
||||
- fixed bug with command action props
|
||||
- eq, eq_ab getters now return boolean values
|
||||
- fixed bug with command action props
|
||||
|
||||
## [2.2.0] - 2022-01-19
|
||||
|
||||
### Added
|
||||
|
||||
- Add VMRemoteErrors class and subclass other error classes.
|
||||
- Expose lower level setters and getters as well as polling parameters through Remote class.
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.2 added to PSGAllery
|
||||
- Add VMRemoteErrors class and subclass other error classes.
|
||||
- Expose lower level setters and getters as well as polling parameters through Remote class.
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.2 added to PSGAllery
|
||||
|
||||
### Changed
|
||||
|
||||
- Rework set many parameters so class properties are set through the wrapper instead by VBVMR_SetParameters
|
||||
- Rework meta module. Separate functions for each member type.
|
||||
- Update pester tests to reflect latest changes
|
||||
- Add throw LoginError if multiple login attempts are made. In testing the session was still crashing, however.
|
||||
- Rework set many parameters so class properties are set through the wrapper instead by VBVMR_SetParameters
|
||||
- Rework meta module. Separate functions for each member type.
|
||||
- Update pester tests to reflect latest changes
|
||||
- Add throw LoginError if multiple login attempts are made. In testing the session was still crashing, however.
|
||||
|
||||
## [2.1.0] - 2022-01-11
|
||||
|
||||
### Added
|
||||
|
||||
- Special command lock
|
||||
- Special command showvbanchat
|
||||
- vban.enable command added (toggle vban)
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.1 added to PSGAllery
|
||||
- Special command lock
|
||||
- Special command showvbanchat
|
||||
- vban.enable command added (toggle vban)
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.1 added to PSGAllery
|
||||
|
||||
### Changed
|
||||
|
||||
- Subclass strip and bus classes into physical/virtual buses.
|
||||
- Subclass strip and bus classes into physical/virtual buses.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Special command showvbanchat now accepts boolean
|
||||
- Special command showvbanchat now accepts boolean
|
||||
|
||||
## [2.0.0] - 2022-01-06
|
||||
|
||||
### Added
|
||||
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.0 added to PSGAllery
|
||||
- README and CHANGELOG updated to reflect latest changes.
|
||||
- Version 2.0 added to PSGAllery
|
||||
|
||||
### Changed
|
||||
|
||||
- Moved meta functions into own module
|
||||
- Vban class now custom object comprising of two arrays of subclasses for each stream type
|
||||
- Major version bumped due to changes to vban class
|
||||
- Pester tests updated to reflect changes.
|
||||
- Moved meta functions into own module
|
||||
- Vban class now custom object comprising of two arrays of subclasses for each stream type
|
||||
- Major version bumped due to changes to vban class
|
||||
- Pester tests updated to reflect changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Special commands now throw write only error on read attempt.
|
||||
- Special commands now throw write only error on read attempt.
|
||||
|
||||
## [1.8.0] - 2021-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- Added special commands
|
||||
- Added special commands
|
||||
|
||||
### Changed
|
||||
|
||||
- Add special section to README
|
||||
- Add special section to README
|
||||
|
||||
### Fixed
|
||||
|
||||
- Removed unneeded console output
|
||||
- Removed unneeded console output
|
||||
|
||||
## [1.6.0] - 2021-06-06
|
||||
|
||||
### Added
|
||||
|
||||
- Add vban commands
|
||||
- Added meta functions for bus/strip attrs
|
||||
- Add vban commands
|
||||
- Added meta functions for bus/strip attrs
|
||||
|
||||
### Changed
|
||||
|
||||
- Update tests to reflect changes
|
||||
- Add vban section to README
|
||||
- Update tests to reflect changes
|
||||
- Add vban section to README
|
||||
|
||||
### Fixed
|
||||
|
||||
- Run 64bit exe for potato version if on 64bit OS
|
||||
- Run 64bit exe for potato version if on 64bit OS
|
||||
|
||||
## [1.5.0] - 2021-05-11
|
||||
|
||||
### Added
|
||||
|
||||
- Fetch dll path through registry (support for 32 and 64 bit)
|
||||
- Add strip/bus commands section to README
|
||||
- Add label name command to Strips
|
||||
- Fetch dll path through registry (support for 32 and 64 bit)
|
||||
- Add strip/bus commands section to README
|
||||
- Add label name command to Strips
|
||||
|
||||
## [1.4.0] - 2021-05-03
|
||||
|
||||
### Added
|
||||
|
||||
- Add gain, comp, limit to Strips
|
||||
- Update tests to reflect changes
|
||||
- Add logging + summary for tests
|
||||
- Add info to README about powershellget, nuget and psgallery
|
||||
- Support other types of params in multi_set
|
||||
- Add gain, comp, limit to Strips
|
||||
- Update tests to reflect changes
|
||||
- Add logging + summary for tests
|
||||
- Add info to README about powershellget, nuget and psgallery
|
||||
- Support other types of params in multi_set
|
||||
|
||||
### Changed
|
||||
|
||||
- Multi_Set now accepts nested hash
|
||||
- Multi_Set now accepts nested hash
|
||||
|
||||
## [1.3.0] - 2021-04-30
|
||||
|
||||
### Added
|
||||
|
||||
- Updated README to include Installation instructions.
|
||||
- Added FROM_SOURCE.md to explain alternative loading of scripts if directly
|
||||
downloaded.
|
||||
- Set_Multi command for setting many parameters at once.
|
||||
- Updated README to include Installation instructions.
|
||||
- Added FROM_SOURCE.md to explain alternative loading of scripts if directly
|
||||
downloaded.
|
||||
- Set_Multi command for setting many parameters at once.
|
||||
|
||||
## [1.0.0] - 2021-04-29
|
||||
|
||||
- Added module to PSGAllery
|
||||
- Added module to PSGAllery
|
||||
|
||||
343
README.md
343
README.md
@@ -8,14 +8,14 @@ For past/future changes to this project refer to: [CHANGELOG](CHANGELOG.md)
|
||||
|
||||
## Tested against
|
||||
|
||||
- Basic 1.0.8.8
|
||||
- Banana 2.0.6.8
|
||||
- Potato 3.0.2.8
|
||||
- Basic 1.0.8.8
|
||||
- Banana 2.0.6.8
|
||||
- Potato 3.0.2.8
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Voicemeeter](https://voicemeeter.com/)
|
||||
- Powershell 5.1+ or Powershell 7.2+
|
||||
- [Voicemeeter](https://voicemeeter.com/)
|
||||
- Powershell 5.1+ or Powershell 7.2+
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -35,9 +35,9 @@ When prompted you will need to accept PSGallery as a trusted repository.
|
||||
|
||||
More Info:
|
||||
|
||||
- [PowerShellGet](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7.1)
|
||||
- [NuGet](https://www.powershellgallery.com/packages/NuGet/1.3.3)
|
||||
- [PSGallery](https://docs.microsoft.com/en-gb/powershell/scripting/gallery/overview?view=powershell-7.1)
|
||||
- [PowerShellGet](https://docs.microsoft.com/en-us/powershell/scripting/gallery/installing-psget?view=powershell-7.1)
|
||||
- [NuGet](https://www.powershellgallery.com/packages/NuGet/1.3.3)
|
||||
- [PSGallery](https://docs.microsoft.com/en-gb/powershell/scripting/gallery/overview?view=powershell-7.1)
|
||||
|
||||
#### Direct download:
|
||||
|
||||
@@ -75,14 +75,14 @@ finally { $vmr.Logout() }
|
||||
|
||||
Voicemeeter factory function can be:
|
||||
|
||||
- Get-RemoteBasic
|
||||
- Get-RemoteBanana
|
||||
- Get-RemotePotato
|
||||
- Get-RemoteBasic
|
||||
- Get-RemoteBanana
|
||||
- Get-RemotePotato
|
||||
|
||||
Added in v3 you may also use the following entry/exit points:
|
||||
Added in `v3` you may also use the following entry/exit points:
|
||||
|
||||
- Connect-Voicemeeter
|
||||
- Disconnect-Voicemeeter
|
||||
- Connect-Voicemeeter
|
||||
- Disconnect-Voicemeeter
|
||||
|
||||
`Connect-Voicemeeter` takes a single parameter `Kind`.
|
||||
|
||||
@@ -90,6 +90,8 @@ for example:
|
||||
|
||||
```powershell
|
||||
$vmr = Connect-Voicemeeter -Kind "potato"
|
||||
...
|
||||
Disconnect-Voicemeeter
|
||||
```
|
||||
|
||||
#### `Through the Shell`
|
||||
@@ -113,31 +115,31 @@ $vmr.Logout()
|
||||
|
||||
The following strip commands are available:
|
||||
|
||||
- mute: boolean
|
||||
- mono: boolean
|
||||
- mc: boolean
|
||||
- k: int, from 0 to 4
|
||||
- solo: boolean
|
||||
- A1-A5: boolean
|
||||
- B1-B3: boolean
|
||||
- limit: int, from -40 to 12
|
||||
- gain: float, from -60.0 to 12.0
|
||||
- label: string
|
||||
- reverb: float, from 0.0 to 10.0
|
||||
- delay: float, from 0.0 to 10.0
|
||||
- fx1: float, from 0.0 to 10.0
|
||||
- fx2: float, from 0.0 to 10.0
|
||||
- pan_x: float, from -0.5 to 0.5
|
||||
- pan_y: float, from 0.0 to 1.0
|
||||
- color_x: float, from -0.5 to 0.5
|
||||
- color_y: float, from 0.0 to 1.0
|
||||
- fx_x: float, from -0.5 to 0.5
|
||||
- fx_y: float, from 0.0 to 1.0
|
||||
- postreverb: boolean
|
||||
- postdelay: boolean
|
||||
- postfx1: boolean
|
||||
- postfx2: boolean
|
||||
- gainlayer0-gainlayer7: float
|
||||
- mute: bool
|
||||
- mono: bool
|
||||
- mc: bool
|
||||
- k: int, from 0 to 4
|
||||
- solo: bool
|
||||
- A1-A5: bool
|
||||
- B1-B3: bool
|
||||
- limit: int, from -40 to 12
|
||||
- gain: float, from -60.0 to 12.0
|
||||
- label: string
|
||||
- reverb: float, from 0.0 to 10.0
|
||||
- delay: float, from 0.0 to 10.0
|
||||
- fx1: float, from 0.0 to 10.0
|
||||
- fx2: float, from 0.0 to 10.0
|
||||
- pan_x: float, from -0.5 to 0.5
|
||||
- pan_y: float, from 0.0 to 1.0
|
||||
- color_x: float, from -0.5 to 0.5
|
||||
- color_y: float, from 0.0 to 1.0
|
||||
- fx_x: float, from -0.5 to 0.5
|
||||
- fx_y: float, from 0.0 to 1.0
|
||||
- postreverb: bool
|
||||
- postdelay: bool
|
||||
- postfx1: bool
|
||||
- postfx2: bool
|
||||
- gainlayer0-gainlayer7: float
|
||||
|
||||
for example:
|
||||
|
||||
@@ -155,15 +157,15 @@ mc, k for virtual strips only.
|
||||
|
||||
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
|
||||
- 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: bool
|
||||
|
||||
for example:
|
||||
|
||||
@@ -175,13 +177,13 @@ $vmr.strip[3].comp.attack = 8.5
|
||||
|
||||
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
|
||||
- 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:
|
||||
|
||||
@@ -193,7 +195,7 @@ $vmr.strip[3].gate.threshold = -40.5
|
||||
|
||||
The following strip.denoiser commands are available:
|
||||
|
||||
- knob: float, from 0.0 to 10.0
|
||||
- knob: float, from 0.0 to 10.0
|
||||
|
||||
for example:
|
||||
|
||||
@@ -203,8 +205,8 @@ $vmr.strip[3].denoiser.knob = 5
|
||||
|
||||
#### AppGain | AppMute
|
||||
|
||||
- `AppGain(amount, gain)` : string, float
|
||||
- `AppMute(amount, mutestate)` : string, boolean
|
||||
- `AppGain(amount, gain)` : string, float
|
||||
- `AppMute(amount, mutestate)` : string, bool
|
||||
|
||||
for example:
|
||||
|
||||
@@ -213,19 +215,33 @@ $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
|
||||
|
||||
The following bus commands are available:
|
||||
|
||||
- mute: bool
|
||||
- mono: bool
|
||||
- limit: int, from -40 to 12
|
||||
- gain: float, from -60.0 to 12.0
|
||||
- label: string
|
||||
- returnreverb: float, from 0.0 to 10.0
|
||||
- returndelay: float, from 0.0 to 10.0
|
||||
- returnfx1: float, from 0.0 to 10.0
|
||||
- returnfx2: float, from 0.0 to 10.0
|
||||
- mute: bool
|
||||
- mono: bool
|
||||
- limit: int, from -40 to 12
|
||||
- gain: float, from -60.0 to 12.0
|
||||
- label: string
|
||||
- returnreverb: float, from 0.0 to 10.0
|
||||
- returndelay: float, from 0.0 to 10.0
|
||||
- returnfx1: float, from 0.0 to 10.0
|
||||
- returnfx2: float, from 0.0 to 10.0
|
||||
|
||||
for example:
|
||||
|
||||
@@ -237,22 +253,22 @@ $vmr.bus[3].returnreverb = 5.7
|
||||
|
||||
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
|
||||
- normal: bool
|
||||
- amix: bool
|
||||
- bmix: bool
|
||||
- repeat: bool
|
||||
- composite: bool
|
||||
- tvmix: bool
|
||||
- upmix21: bool
|
||||
- upmix41: bool
|
||||
- upmix61: bool
|
||||
- centeronly: bool
|
||||
- lfeonly: bool
|
||||
- rearonly: bool
|
||||
|
||||
The following bus.mode commands are available:
|
||||
|
||||
- Get(): returns the current bus mode.
|
||||
- Get(): returns the current bus mode.
|
||||
|
||||
for example:
|
||||
|
||||
@@ -262,18 +278,30 @@ $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
|
||||
|
||||
#### device
|
||||
|
||||
The following strip.device | bus.device commands are available:
|
||||
|
||||
- name: string
|
||||
- sr: int
|
||||
- wdm: string
|
||||
- ks: string
|
||||
- mme: string
|
||||
- asio: string
|
||||
- name: string
|
||||
- sr: int
|
||||
- wdm: string
|
||||
- ks: string
|
||||
- mme: string
|
||||
- asio: string
|
||||
|
||||
for example:
|
||||
|
||||
@@ -289,13 +317,20 @@ wdm, ks, mme, asio are defined as write only.
|
||||
|
||||
The following strip.eq | bus.eq commands are available:
|
||||
|
||||
- on: boolean
|
||||
- ab: boolean
|
||||
- on: bool
|
||||
- ab: bool
|
||||
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.strip[0].eq.on = $true
|
||||
$vmr.bus[0].eq.ab = $false
|
||||
```
|
||||
|
||||
#### FadeTo | FadeBy
|
||||
|
||||
- `FadeTo(amount, time)` : float, int
|
||||
- `FadeBy(amount, time)` : float, int
|
||||
- `FadeTo(amount, time)` : float, int
|
||||
- `FadeBy(amount, time)` : float, int
|
||||
|
||||
Modify gain to or by the selected amount in db over a time interval in ms.
|
||||
|
||||
@@ -310,9 +345,9 @@ $vmr.bus[0].FadeBy(-10, 500)
|
||||
|
||||
Three modes defined: state, stateonly and trigger.
|
||||
|
||||
- State runs associated scripts
|
||||
- Stateonly does not run associated scripts
|
||||
- Index range (0, 69)
|
||||
- State runs associated scripts
|
||||
- Stateonly does not run associated scripts
|
||||
- Index range (0, 69)
|
||||
|
||||
```powershell
|
||||
$vmr.button[3].state = $true
|
||||
@@ -324,19 +359,19 @@ $vmr.button[5].trigger = $true
|
||||
|
||||
### VBAN
|
||||
|
||||
- vmr.vban.enable: Toggle VBAN on or off. Accepts a boolean value.
|
||||
- vmr.vban.enable: Toggle VBAN on or off. Accepts a bool value.
|
||||
|
||||
For each vban in/out stream the following parameters are defined:
|
||||
|
||||
- on: boolean
|
||||
- name: string
|
||||
- ip: string
|
||||
- port: int from 1024 - 65535
|
||||
- sr: int (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||
- channel: int from 1 to 8
|
||||
- bit: int 16 or 24
|
||||
- quality: int from 0 to 4
|
||||
- route: int from 0 to 8
|
||||
- on: bool
|
||||
- name: string
|
||||
- ip: string
|
||||
- port: int, from 1024 - 65535
|
||||
- sr: in, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||
- channel: int from 1 to 8
|
||||
- bit: int, 16 or 24
|
||||
- quality: int, from 0 to 4
|
||||
- route: int, from 0 to 8
|
||||
|
||||
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.
|
||||
@@ -355,18 +390,18 @@ $vmr.vban.outstream[3].bit = 16
|
||||
|
||||
Certain 'special' commands are defined by the API as performing actions rather than setting values.
|
||||
|
||||
The following commands are available:
|
||||
|
||||
- show
|
||||
- hide
|
||||
- restart
|
||||
- shutdown
|
||||
- showvbanchat: bool, (write only)
|
||||
- lock: bool, (write only)
|
||||
|
||||
The following methods are available:
|
||||
|
||||
- show
|
||||
- hide
|
||||
- restart
|
||||
- shutdown
|
||||
- Load(filepath)
|
||||
|
||||
The following properties are write only and accept boolean values:
|
||||
|
||||
- showvbanchat
|
||||
- lock
|
||||
- Load($filepath): string
|
||||
|
||||
example:
|
||||
|
||||
@@ -380,27 +415,61 @@ $vmr.command.Load("path/to/filename.xml")
|
||||
|
||||
### Recorder
|
||||
|
||||
The following commands are available:
|
||||
|
||||
- play
|
||||
- stop
|
||||
- pause
|
||||
- record
|
||||
- ff
|
||||
- rew
|
||||
- A1 - A5: bool
|
||||
- B1 - B3: bool
|
||||
- samplerate: int, (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||
- bitresolution: int, (8, 16, 24, 32)
|
||||
- channel: int, from 1 to 8
|
||||
- kbps: int, (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
|
||||
|
||||
The following methods are available:
|
||||
|
||||
- play
|
||||
- stop
|
||||
- pause
|
||||
- record
|
||||
- ff
|
||||
- rew
|
||||
|
||||
The following properties accept boolean values.
|
||||
|
||||
- loop
|
||||
- A1 - A5
|
||||
- B1 - B3
|
||||
- Load($filepath): string
|
||||
- GoTo($timestring): string, must match the format 'hh:mm:ss'
|
||||
- FileType($format): string, ('wav', 'aiff', 'bwf', 'mp3')
|
||||
|
||||
example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.play
|
||||
$vmr.recorder.A1 = $true
|
||||
|
||||
$vmr.recorder.loop = $true
|
||||
$vmr.recorder.GoTo("00:01:15") # go to 1min 15sec into track
|
||||
```
|
||||
|
||||
#### Mode
|
||||
|
||||
The following commands are available:
|
||||
|
||||
- recbus
|
||||
- playonload
|
||||
- loop
|
||||
- multitrack
|
||||
|
||||
example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.mode.loop = $true
|
||||
```
|
||||
|
||||
#### ArmStrip[i]|ArmBus[i]
|
||||
|
||||
The following method is available:
|
||||
|
||||
- Set($val): bool
|
||||
|
||||
example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.armstrip[0].Set($true)
|
||||
```
|
||||
|
||||
### Multiple parameters
|
||||
@@ -451,9 +520,9 @@ will load a config file at profiles/banana/config.psd1 for Voicemeeter Banana.
|
||||
|
||||
Access to lower level Getters and Setters are provided with these functions:
|
||||
|
||||
- `$vmr.Getter(param)`: For getting the value of a parameter expected to return a value other than string.
|
||||
- `$vmr.Getter_String(param)`: For getting the value of any parameter expected to return a string.
|
||||
- `$vmr.Setter(param, value)`: For setting the value of any parameter.
|
||||
- `$vmr.Getter(param)`: For getting the value of a parameter expected to return a value other than string.
|
||||
- `$vmr.Getter_String(param)`: For getting the value of any parameter expected to return a string.
|
||||
- `$vmr.Setter(param, value)`: For setting the value of any parameter.
|
||||
|
||||
```powershell
|
||||
$vmr.Getter('Strip[2].Mute')
|
||||
@@ -462,7 +531,7 @@ $vmr.Setter('Strip[4].Label', 'stripname')
|
||||
$vmr.Setter('Strip[0].Gain', -3.6)
|
||||
```
|
||||
|
||||
- `$vmr.SendText`: Set parameters by script
|
||||
- `$vmr.SendText`: Set parameters by script
|
||||
|
||||
```powershell
|
||||
$vmr.SendText("strip[0].mute=1;strip[2].gain=3.8;bus[1].eq.On=1")
|
||||
@@ -470,17 +539,17 @@ $vmr.Setter('Strip[0].Gain', -3.6)
|
||||
|
||||
Access to lower level polling functions are provided with these functions:
|
||||
|
||||
- `$vmr.PDirty`: Returns true if a parameter has been updated.
|
||||
- `$vmr.MDirty`: Returns true if a macrobutton has been updated.
|
||||
- `$vmr.PDirty`: Returns true if a parameter has been updated.
|
||||
- `$vmr.MDirty`: Returns true if a macrobutton has been updated.
|
||||
|
||||
### Run tests
|
||||
|
||||
Run tests using .\tests\pre-commit.ps1 which accepts the following parameters:
|
||||
|
||||
- `kind`: Run tests of this kind
|
||||
- `tag`: Run tests tagged with this marker (currently `higher` or `lower`)
|
||||
- `num`: Run this number of tests
|
||||
- `log`: Write summary log file
|
||||
- `kind`: Run tests of this kind
|
||||
- `tag`: Run tests tagged with this marker (currently `higher` or `lower`)
|
||||
- `num`: Run this number of tests
|
||||
- `log`: Write summary log file
|
||||
|
||||
Run tests from repository root in a subshell and write logs, like so:
|
||||
|
||||
@@ -488,4 +557,4 @@ Run tests from repository root in a subshell and write logs, like so:
|
||||
|
||||
### Official Documentation
|
||||
|
||||
- [Voicemeeter Remote C API](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/update-docs/VoicemeeterRemoteAPI.pdf)
|
||||
- [Voicemeeter Remote C API](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/update-docs/VoicemeeterRemoteAPI.pdf)
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
[switch]$interactive,
|
||||
[switch]$output,
|
||||
[String]$kind = "banana",
|
||||
[String[]]$script = @()
|
||||
)
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
|
||||
$VerbosePreference = "Continue"
|
||||
|
||||
function get-value {
|
||||
param([object]$vmr, [string]$line)
|
||||
try {
|
||||
@@ -24,16 +22,16 @@ function msgHandler {
|
||||
param([object]$vmr, [string]$line)
|
||||
$line + " passed to handler" | Write-Debug
|
||||
if ($line[0] -eq "!") {
|
||||
if ($output) { "Toggling " + $line.substring(1) | Write-Host }
|
||||
"Toggling " + $line.substring(1) | Write-Debug
|
||||
$retval = get-value -vmr $vmr -line $line.substring(1)
|
||||
$vmr.Setter($line.substring(1), 1 - $retval)
|
||||
}
|
||||
elseif ($line.Contains("=")) {
|
||||
if ($output) { "Setting $line" | Write-Host }
|
||||
"Setting $line" | Write-Debug
|
||||
$vmr.SendText($line)
|
||||
}
|
||||
else {
|
||||
if ($output) { "Getting $line" | Write-Host }
|
||||
"Getting $line" | Write-Debug
|
||||
$retval = get-value -vmr $vmr -line $line
|
||||
$line + " = " + $retval | Write-Host
|
||||
}
|
||||
@@ -63,4 +61,4 @@ function main {
|
||||
finally { Disconnect-Voicemeeter }
|
||||
}
|
||||
|
||||
if ($MyInvocation.InvocationName -ne '.') { main }
|
||||
main
|
||||
|
||||
@@ -7,27 +7,30 @@
|
||||
Credits go to @bobsupercow
|
||||
#>
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
$VerbosePreference = "Continue"
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
|
||||
try {
|
||||
$vmr = Connect-Voicemeeter -Kind "potato"
|
||||
|
||||
$buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6])
|
||||
"Buses in selection: $($buses)"
|
||||
$unmutedIndex = $null
|
||||
|
||||
# 1)
|
||||
"Cycling through bus selection to check for first unmuted Bus..." | Write-Host
|
||||
foreach ($bus in $buses) {
|
||||
# 2)
|
||||
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)
|
||||
$bus.mute = $true
|
||||
|
||||
# 3)
|
||||
if ($buses[++$unmutedIndex]) {
|
||||
"unmuting bus $($buses[$unmutedIndex].index)" | Write-Host
|
||||
"Unmuting Bus $($buses[$unmutedIndex].index)" | Write-Host
|
||||
$buses[$unmutedIndex].mute = $false
|
||||
break
|
||||
}
|
||||
@@ -37,7 +40,7 @@ try {
|
||||
# 4)
|
||||
if ($null -eq $unmutedIndex) {
|
||||
$buses[0].mute = $false
|
||||
"unmuting bus $($buses[0].index)" | Write-Host
|
||||
"Unmuting Bus $($buses[0].index)" | Write-Host
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
Import-Module obs-powershell
|
||||
|
||||
$VerbosePreference = "Continue"
|
||||
|
||||
function CurrentProgramSceneChanged {
|
||||
param([System.Object]$data)
|
||||
Write-Host "Switched to scene", $data.sceneName
|
||||
@@ -10,19 +11,15 @@ function CurrentProgramSceneChanged {
|
||||
switch ($data.sceneName) {
|
||||
"START" {
|
||||
$vmr.strip[0].mute = !$vmr.strip[0].mute
|
||||
"Toggling Strip 0 mute"
|
||||
}
|
||||
"BRB" {
|
||||
$vmr.strip[0].gain = -8.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 }
|
||||
}
|
||||
@@ -68,4 +65,4 @@ function main {
|
||||
}
|
||||
}
|
||||
|
||||
if ($MyInvocation.InvocationName -ne '.') { main }
|
||||
main
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
. $PSScriptRoot\kinds.ps1
|
||||
. $PSScriptRoot\errors.ps1
|
||||
. $PSScriptRoot\meta.ps1
|
||||
. $PSScriptRoot\base.ps1
|
||||
. $PSScriptRoot\kinds.ps1
|
||||
. $PSScriptRoot\strip.ps1
|
||||
. $PSScriptRoot\bus.ps1
|
||||
. $PSScriptRoot\macrobuttons.ps1
|
||||
. $PSScriptRoot\vban.ps1
|
||||
. $PSScriptRoot\command.ps1
|
||||
. $PSScriptRoot\recorder.ps1
|
||||
. $PSScriptRoot\profiles.ps1
|
||||
|
||||
class Remote {
|
||||
[String]$vmpath
|
||||
[Hashtable]$kind
|
||||
[Object]$profiles
|
||||
|
||||
Remote ([String]$kindId) {
|
||||
if (!(Setup_DLL)) {
|
||||
Exit -1
|
||||
}
|
||||
$this.vmpath = Setup_DLL
|
||||
$this.kind = GetKind($kindId)
|
||||
$this.profiles = Get_Profiles($this.kind.name)
|
||||
}
|
||||
@@ -31,7 +39,7 @@ class Remote {
|
||||
}
|
||||
|
||||
[String] GetVersion() {
|
||||
return Version
|
||||
return VmVersion
|
||||
}
|
||||
|
||||
[void] Set_Profile([String]$config) {
|
||||
@@ -75,7 +83,7 @@ class RemoteBasic : Remote {
|
||||
$this.bus = Make_Buses($this)
|
||||
$this.button = Make_Buttons
|
||||
$this.vban = Make_Vban($this)
|
||||
$this.command = Make_Command
|
||||
$this.command = Make_Command($this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +100,7 @@ class RemoteBanana : Remote {
|
||||
$this.bus = Make_Buses($this)
|
||||
$this.button = Make_Buttons
|
||||
$this.vban = Make_Vban($this)
|
||||
$this.command = Make_Command
|
||||
$this.command = Make_Command($this)
|
||||
$this.recorder = Make_Recorder($this)
|
||||
}
|
||||
}
|
||||
@@ -110,7 +118,7 @@ class RemotePotato : Remote {
|
||||
$this.bus = Make_Buses($this)
|
||||
$this.button = Make_Buttons
|
||||
$this.vban = Make_Vban($this)
|
||||
$this.command = Make_Command
|
||||
$this.command = Make_Command($this)
|
||||
$this.recorder = Make_Recorder($this)
|
||||
}
|
||||
}
|
||||
@@ -129,24 +137,20 @@ Function 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
|
||||
}
|
||||
switch ($Kind) {
|
||||
"basic" {
|
||||
return Get-RemoteBasic
|
||||
}
|
||||
"banana" {
|
||||
return Get-RemoteBanana
|
||||
}
|
||||
"potato" {
|
||||
return Get-RemotePotato
|
||||
}
|
||||
default {
|
||||
throw [LoginError]::new("Unknown Voicemeeter kind `"$Kind`"")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Disconnect-Voicemeeter {
|
||||
|
||||
176
lib/base.ps1
176
lib/base.ps1
@@ -1,74 +1,77 @@
|
||||
. $PSScriptRoot\errors.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 {
|
||||
param(
|
||||
[string]$kindId
|
||||
)
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Login()
|
||||
if (-not $retval) {
|
||||
"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 })
|
||||
}
|
||||
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_RunVoicemeeter([int64]$vmExe)
|
||||
if (-not $retval) {
|
||||
"STARTING VOICEMEETER" | Write-Verbose
|
||||
Start-Sleep -s 1
|
||||
}
|
||||
else {
|
||||
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) }
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Login()
|
||||
if ($retval -notin @(0, 1, -2)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_Login")
|
||||
}
|
||||
catch [LoginError] {
|
||||
Write-Warning "$($_.Exception.ErrorMessage()). Fatal error, exiting..."
|
||||
exit -2
|
||||
|
||||
switch ($retval) {
|
||||
1 {
|
||||
"Voicemeeter Engine running but GUI not launched. Launching GUI now." | Write-Verbose
|
||||
RunVoicemeeter -kindId $kindId
|
||||
}
|
||||
-2 {
|
||||
throw [LoginError]::new("Login may only be called once per session.")
|
||||
}
|
||||
}
|
||||
|
||||
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
|
||||
"VERSION:[" + $(VmType).ToUpper() + "]" | Write-Verbose
|
||||
"Successfully logged into Voicemeeter [" + $(VmType).ToUpper() + "] Version " + $(VmVersion) | Write-Verbose
|
||||
}
|
||||
|
||||
function Logout {
|
||||
Start-Sleep -m 20
|
||||
Start-Sleep -m 100
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Logout()
|
||||
if (-not $retval) { "LOGGED OUT" | Write-Verbose }
|
||||
if ($retval -notin @(0)) {
|
||||
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 {
|
||||
[bool][Voicemeeter.Remote]::VBVMR_IsParametersDirty()
|
||||
$retval = [Voicemeeter.Remote]::VBVMR_IsParametersDirty()
|
||||
if ($retval -notin @(0, 1)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_RunVoicemeeter")
|
||||
}
|
||||
[bool]$retval
|
||||
}
|
||||
|
||||
function M_Dirty {
|
||||
[bool][Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty()
|
||||
$retval = [Voicemeeter.Remote]::VBVMR_MacroButton_IsDirty()
|
||||
if ($retval -notin @(0, 1)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_RunVoicemeeter")
|
||||
}
|
||||
[bool]$retval
|
||||
}
|
||||
|
||||
function VmType {
|
||||
New-Variable -Name ptr -Value 0
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterType([ref]$ptr)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterType")
|
||||
}
|
||||
switch ($ptr) {
|
||||
1 { return "basic" }
|
||||
2 { return "banana" }
|
||||
@@ -76,10 +79,12 @@ function VmType {
|
||||
}
|
||||
}
|
||||
|
||||
function Version {
|
||||
function VmVersion {
|
||||
New-Variable -Name ptr -Value 0
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetVoicemeeterVersion([ref]$ptr)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_GetVoicemeeterVersion")
|
||||
}
|
||||
$v1 = ($ptr -band 0xFF000000) -shr 24
|
||||
$v2 = ($ptr -band 0x00FF0000) -shr 16
|
||||
$v3 = ($ptr -band 0x0000FF00) -shr 8
|
||||
@@ -92,28 +97,22 @@ function Param_Get {
|
||||
param(
|
||||
[string]$PARAM, [bool]$IS_STRING = $false
|
||||
)
|
||||
Start-Sleep -m 50
|
||||
Start-Sleep -m 30
|
||||
while (P_Dirty) { Start-Sleep -m 1 }
|
||||
|
||||
if ($IS_STRING) {
|
||||
$BYTES = [System.Byte[]]::new(512)
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterStringA($PARAM, $BYTES)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_GetParameterStringA")
|
||||
}
|
||||
[System.Text.Encoding]::ASCII.GetString($BYTES).Trim([char]0)
|
||||
}
|
||||
else {
|
||||
New-Variable -Name ptr -Value 0.0
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetParameterFloat($PARAM, [ref]$ptr)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_GetParameterFloat")
|
||||
}
|
||||
[single]$ptr
|
||||
}
|
||||
@@ -123,17 +122,17 @@ function Param_Set {
|
||||
param(
|
||||
[string]$PARAM, [Object]$VALUE
|
||||
)
|
||||
try {
|
||||
if ($VALUE -is [string]) {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE)
|
||||
if ($VALUE -is [string]) {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterStringA($PARAM, $VALUE)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_SetParameterStringA")
|
||||
}
|
||||
else {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
|
||||
}
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
else {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_SetParameterFloat")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +140,9 @@ function MB_Set {
|
||||
param(
|
||||
[int64]$ID, [single]$SET, [int64]$MODE
|
||||
)
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_SetStatus($ID, $SET, $MODE)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_MacroButton_SetStatus")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +154,9 @@ function MB_Get {
|
||||
while (M_Dirty) { Start-Sleep -m 1 }
|
||||
|
||||
New-Variable -Name ptr -Value 0.0
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_MacroButton_GetStatus($ID, [ref]$ptr, $MODE)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, $MyInvocation.MyCommand)
|
||||
}
|
||||
[int]$ptr
|
||||
}
|
||||
@@ -195,11 +188,20 @@ function Set_By_Script {
|
||||
param(
|
||||
[string]$script
|
||||
)
|
||||
try {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
|
||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
||||
}
|
||||
catch [CAPIError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_SetParameters")
|
||||
}
|
||||
}
|
||||
|
||||
function Get_Level {
|
||||
param(
|
||||
[int64]$MODE, [int64]$INDEX
|
||||
)
|
||||
New-Variable -Name ptr -Value 0.0
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_GetLevel($MODE, $INDEX, [ref]$ptr)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, "VBVMR_GetLevel")
|
||||
}
|
||||
[float]$ptr
|
||||
}
|
||||
@@ -1,18 +1,11 @@
|
||||
function Setup_DLL {
|
||||
try {
|
||||
$vb_path = Get_VBPath
|
||||
. $PSScriptRoot\inst.ps1
|
||||
|
||||
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 { "" } }) + `
|
||||
".dll")
|
||||
}
|
||||
catch [VMRemoteError] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
return $false
|
||||
}
|
||||
function Setup_DLL {
|
||||
$VMPATH = Get_VMPath
|
||||
|
||||
$dll = Join-Path -Path $VMPATH -ChildPath ("VoicemeeterRemote" + `
|
||||
(& { if ([Environment]::Is64BitOperatingSystem) { "64" } else { "" } }) + `
|
||||
".dll")
|
||||
|
||||
$Signature = @"
|
||||
[DllImport(@"$dll")]
|
||||
@@ -47,8 +40,11 @@ function Setup_DLL {
|
||||
|
||||
[DllImport(@"$dll")]
|
||||
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
|
||||
return $true
|
||||
return $VMPATH
|
||||
}
|
||||
|
||||
79
lib/bus.ps1
79
lib/bus.ps1
@@ -1,5 +1,3 @@
|
||||
. $PSScriptRoot\meta.ps1
|
||||
|
||||
class IBus {
|
||||
[int]$index
|
||||
[Object]$remote
|
||||
@@ -13,34 +11,46 @@ class IBus {
|
||||
return "Bus[" + $this.index + "]"
|
||||
}
|
||||
|
||||
[string] ToString() {
|
||||
return $this.GetType().Name + $this.index
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
|
||||
$this.ToString() + " Getter: $($this.Cmd($param))" | Write-Debug
|
||||
return $this.remote.Getter($this.Cmd($param))
|
||||
}
|
||||
|
||||
[string] Getter_String ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
|
||||
$this.ToString() + " Getter_String: $($this.Cmd($param))" | Write-Debug
|
||||
return $this.remote.Getter_String($this.Cmd($param))
|
||||
}
|
||||
|
||||
[void] Setter ($param, $set) {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $set
|
||||
[void] Setter ($param, $val) {
|
||||
$this.ToString() + " Setter: $($this.Cmd($param))=$val" | Write-Debug
|
||||
$this.remote.Setter($this.Cmd($param), $val)
|
||||
}
|
||||
|
||||
[string] Cmd ($param) {
|
||||
if ([string]::IsNullOrEmpty($param)) {
|
||||
return $this.identifier()
|
||||
}
|
||||
return "$($this.identifier()).$param"
|
||||
}
|
||||
}
|
||||
|
||||
class Bus : IBus {
|
||||
[Object]$mode
|
||||
[Object]$eq
|
||||
[Object]$levels
|
||||
|
||||
Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('mono', 'mute')
|
||||
AddStringMembers -PARAMS @('label')
|
||||
AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
|
||||
|
||||
$this.mode = [Mode]::new($index, $remote)
|
||||
$this.eq = [Eq]::new($index, $remote)
|
||||
$this.mode = [BusMode]::new($index, $remote)
|
||||
$this.eq = [BusEq]::new($index, $remote)
|
||||
$this.levels = [BusLevels]::new($index, $remote)
|
||||
}
|
||||
|
||||
[string] ToString() {
|
||||
return $this.GetType().Name + $this.index
|
||||
}
|
||||
|
||||
[void] FadeTo ([single]$target, [int]$time) {
|
||||
@@ -52,10 +62,41 @@ class Bus : IBus {
|
||||
}
|
||||
}
|
||||
|
||||
class Mode : IBus {
|
||||
class BusLevels : IBus {
|
||||
[int]$init
|
||||
[int]$offset
|
||||
|
||||
BusLevels ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
$this.init = $index * 8
|
||||
$this.offset = 8
|
||||
}
|
||||
|
||||
[float] Convert([float]$val) {
|
||||
if ($val -gt 0) {
|
||||
return [math]::Round(20 * [math]::Log10($val), 1)
|
||||
}
|
||||
else {
|
||||
return - 200.0
|
||||
}
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] Getter([int]$mode) {
|
||||
[System.Collections.ArrayList]$vals = @()
|
||||
$this.init..$($this.init + $this.offset - 1) | ForEach-Object {
|
||||
$vals.Add($this.Convert($(Get_Level -MODE $mode -INDEX $_)))
|
||||
}
|
||||
return $vals
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] All() {
|
||||
return $this.Getter(3)
|
||||
}
|
||||
}
|
||||
|
||||
class BusMode : IBus {
|
||||
[System.Collections.ArrayList]$modes
|
||||
|
||||
Mode ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
BusMode ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
$this.modes = @(
|
||||
'normal', 'amix', 'bmix', 'repeat', 'composite', 'tvmix', 'upmix21', 'upmix41', 'upmix61',
|
||||
'centeronly', 'lfeonly', 'rearonly'
|
||||
@@ -78,8 +119,8 @@ class Mode : IBus {
|
||||
}
|
||||
}
|
||||
|
||||
class Eq : IBus {
|
||||
Eq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class BusEq : IBus {
|
||||
BusEq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('on', 'ab')
|
||||
}
|
||||
|
||||
@@ -92,12 +133,12 @@ class PhysicalBus : Bus {
|
||||
[Object]$device
|
||||
|
||||
PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
$this.device = [Device]::new($index, $remote)
|
||||
$this.device = [BusDevice]::new($index, $remote)
|
||||
}
|
||||
}
|
||||
|
||||
class Device : IBus {
|
||||
Device ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class BusDevice : IBus {
|
||||
BusDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
. $PSScriptRoot\meta.ps1
|
||||
|
||||
class Special {
|
||||
Special () {
|
||||
[Object]$remote
|
||||
|
||||
Special ([Object]$remote) {
|
||||
AddActionMembers -PARAMS @('restart', 'shutdown', 'show')
|
||||
|
||||
$this.remote = $remote
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
@@ -14,18 +16,28 @@ class Special {
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
|
||||
return $this.remote.Getter("$($this.identifier()).$param")
|
||||
}
|
||||
|
||||
[void] Setter ($param, $val) {
|
||||
if ($val -is [Boolean]) {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 })
|
||||
$this.remote.Setter("$($this.identifier()).$param", $(if ($val) { 1 } else { 0 }))
|
||||
}
|
||||
else {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
|
||||
$this.remote.Setter("$($this.identifier()).$param", $val)
|
||||
}
|
||||
}
|
||||
|
||||
[void] RunMacrobuttons() {
|
||||
"Launching the MacroButtons app" | Write-Verbose
|
||||
Start-Process -FilePath $(Join-Path -Path $this.remote.vmpath -ChildPath "VoicemeeterMacroButtons.exe")
|
||||
}
|
||||
|
||||
[void] CloseMacrobuttons() {
|
||||
"Closing the MacroButtons app" | Write-Verbose
|
||||
Stop-Process -Name "VoicemeeterMacroButtons"
|
||||
}
|
||||
|
||||
hidden $_hide = $($this | Add-Member ScriptProperty 'hide' `
|
||||
{
|
||||
$this._hide = $this.Setter('show', $false)
|
||||
@@ -58,6 +70,6 @@ class Special {
|
||||
}
|
||||
}
|
||||
|
||||
function Make_Command {
|
||||
return [Special]::new()
|
||||
function Make_Command([Object]$remote) {
|
||||
return [Special]::new($remote)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
class VMRemoteError : Exception {
|
||||
[string]$msg
|
||||
|
||||
VMRemoteError ([string]$msg) {
|
||||
$this.msg = $msg
|
||||
}
|
||||
|
||||
[string] ErrorMessage () {
|
||||
return $this.msg
|
||||
VMRemoteError ([string]$msg) : base ($msg) {
|
||||
}
|
||||
}
|
||||
|
||||
class LoginError : VMRemoteError {
|
||||
LoginError ([string]$msg) : base ([string]$msg) {
|
||||
LoginError ([string]$msg) : base ($msg) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +12,8 @@ class CAPIError : VMRemoteError {
|
||||
[int]$retval
|
||||
[string]$caller
|
||||
|
||||
CAPIError ([int]$retval, [string]$caller) {
|
||||
CAPIError ([int]$retval, [string]$caller) : base ("$caller returned $retval") {
|
||||
$this.retval = $retval
|
||||
$this.caller = $caller
|
||||
}
|
||||
|
||||
[string] ErrorMessage () {
|
||||
return "CAPI return value: {0} in {1}" -f $this.retval, $this.caller
|
||||
}
|
||||
}
|
||||
}
|
||||
13
lib/inst.ps1
13
lib/inst.ps1
@@ -1,8 +1,13 @@
|
||||
function Get_VBPath {
|
||||
$reg_path = "Registry::HKEY_LOCAL_MACHINE\Software" + `
|
||||
function Get_VMPath {
|
||||
$REG_KEY = "Registry::HKEY_LOCAL_MACHINE\Software" + `
|
||||
(& { if ([Environment]::Is64BitOperatingSystem) { "\WOW6432Node" } else { "" } }) + `
|
||||
"\Microsoft\Windows\CurrentVersion\Uninstall"
|
||||
$vm_key = "\VB:Voicemeeter {17359A74-1236-5467}\"
|
||||
$VM_KEY = "\VB:Voicemeeter {17359A74-1236-5467}\"
|
||||
|
||||
return $(Get-ItemPropertyValue -Path ($reg_path + $vm_key) -Name UninstallString | Split-Path -Parent)
|
||||
try {
|
||||
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.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
enum ButtonTypes {
|
||||
State = 1
|
||||
StateOnly = 2
|
||||
Trigger = 3
|
||||
}
|
||||
|
||||
class MacroButton {
|
||||
[int32]$index
|
||||
|
||||
@@ -10,40 +16,42 @@ class MacroButton {
|
||||
}
|
||||
|
||||
[int] Getter ($mode) {
|
||||
"Button[$($this.index)].$([ButtonTypes].GetEnumName($mode))" | Write-Debug
|
||||
return MB_Get -Id $this.index -Mode $mode
|
||||
}
|
||||
|
||||
[void] Setter ($set, $mode) {
|
||||
MB_Set -Id $this.index -SET $set -Mode $mode
|
||||
[void] Setter ($val, $mode) {
|
||||
"Button[$($this.index)].$([ButtonTypes].GetEnumName($mode))=$val" | Write-Debug
|
||||
MB_Set -Id $this.index -SET $val -Mode $mode
|
||||
}
|
||||
|
||||
hidden $_state = $($this | Add-Member ScriptProperty 'state' `
|
||||
{
|
||||
[bool]$this.Getter(1)
|
||||
[bool]$this.Getter([ButtonTypes]::State)
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
$this._state = $this.Setter($arg, 1)
|
||||
$this._state = $this.Setter($arg, [ButtonTypes]::State)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' `
|
||||
{
|
||||
[bool]$this.Getter(2)
|
||||
[bool]$this.Getter([ButtonTypes]::StateOnly)
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
$this._stateonly = $this.Setter($arg, 2)
|
||||
$this._stateonly = $this.Setter($arg, [ButtonTypes]::StateOnly)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' `
|
||||
{
|
||||
[bool]$this.Getter(3)
|
||||
[bool]$this.Getter([ButtonTypes]::Trigger)
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
$this._trigger = $this.Setter($arg, 3)
|
||||
$this._trigger = $this.Setter($arg, [ButtonTypes]::Trigger)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,14 +24,9 @@ function Set_Profile {
|
||||
param(
|
||||
[Object]$DATA, [string]$CONF
|
||||
)
|
||||
try {
|
||||
if ($null -eq $DATA -or -not $DATA.$CONF) {
|
||||
throw [VMRemoteErrors]::new("No profile named $CONF was loaded")
|
||||
}
|
||||
Param_Set_Multi -HASH $DATA.$CONF
|
||||
Start-Sleep -m 1
|
||||
}
|
||||
catch [VMRemoteErrors] {
|
||||
Write-Warning $_.Exception.ErrorMessage()
|
||||
if ($null -eq $DATA -or -not $DATA.$CONF) {
|
||||
throw [VMRemoteErrors]::new("No profile named '$CONF' has been loaded into memory.")
|
||||
}
|
||||
Param_Set_Multi -HASH $DATA.$CONF
|
||||
Start-Sleep -m 1
|
||||
}
|
||||
|
||||
194
lib/recorder.ps1
194
lib/recorder.ps1
@@ -1,12 +1,52 @@
|
||||
. $PSScriptRoot\meta.ps1
|
||||
|
||||
class Recorder {
|
||||
class IRecorder {
|
||||
[Object]$remote
|
||||
|
||||
Recorder ([Object]$remote) {
|
||||
IRecorder ([Object]$remote) {
|
||||
$this.remote = $remote
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
$this.Cmd($param) | Write-Debug
|
||||
return $this.remote.Getter($this.Cmd($param))
|
||||
}
|
||||
|
||||
[void] Setter ($param, $val) {
|
||||
"$($this.Cmd($param))=$val" | Write-Debug
|
||||
if ($val -is [Boolean]) {
|
||||
$this.remote.Setter($this.Cmd($param), $(if ($val) { 1 } else { 0 }))
|
||||
}
|
||||
else {
|
||||
$this.remote.Setter($this.Cmd($param), $val)
|
||||
}
|
||||
}
|
||||
|
||||
[string] Cmd ($param) {
|
||||
if ([string]::IsNullOrEmpty($param)) {
|
||||
return $this.identifier()
|
||||
}
|
||||
return "$($this.identifier()).$param"
|
||||
}
|
||||
}
|
||||
|
||||
class Recorder : IRecorder {
|
||||
[Object]$remote
|
||||
[Object]$mode
|
||||
[System.Collections.ArrayList]$armstrip
|
||||
[System.Collections.ArrayList]$armbus
|
||||
|
||||
Recorder ([Object]$remote) : base ($remote) {
|
||||
$this.mode = [RecorderMode]::new($remote)
|
||||
$this.armstrip = @()
|
||||
0..($remote.kind.p_in + $remote.kind.v_in - 1) | ForEach-Object {
|
||||
$this.armstrip.Add([RecorderArmStrip]::new($_, $remote))
|
||||
}
|
||||
$this.armbus = @()
|
||||
0..($remote.kind.p_out + $remote.kind.v_out - 1) | ForEach-Object {
|
||||
$this.armbus.Add([RecorderArmBus]::new($_, $remote))
|
||||
}
|
||||
|
||||
AddActionMembers -PARAMS @('play', 'stop', 'pause', 'replay', 'record', 'ff', 'rew')
|
||||
AddFloatMembers -PARAMS @('gain')
|
||||
AddChannelMembers
|
||||
}
|
||||
|
||||
@@ -18,32 +58,146 @@ class Recorder {
|
||||
return $this.GetType().Name
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
|
||||
}
|
||||
|
||||
[void] Setter ($param, $val) {
|
||||
if ($val -is [Boolean]) {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $(if ($val) { 1 } else { 0 })
|
||||
}
|
||||
else {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
|
||||
}
|
||||
}
|
||||
|
||||
hidden $_loop = $($this | Add-Member ScriptProperty 'loop' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).mode.loop is write only")
|
||||
[bool]$this.mode.loop
|
||||
} `
|
||||
{
|
||||
param([bool]$arg)
|
||||
$this._loop = $this.Setter('mode.loop', $arg)
|
||||
param($arg)
|
||||
$this.mode.loop = $arg
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_samplerate = $($this | Add-Member ScriptProperty 'samplerate' `
|
||||
{
|
||||
$this.Getter('samplerate')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
$opts = @(22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||
if ($opts.Contains($arg)) {
|
||||
$this._samplerate = $this.Setter('samplerate', $arg)
|
||||
}
|
||||
else {
|
||||
"samplerate got: $arg, expected one of $opts" | Write-Warning
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_bitresolution = $($this | Add-Member ScriptProperty 'bitresolution' `
|
||||
{
|
||||
$this.Getter('bitresolution')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
$opts = @(8, 16, 24, 32)
|
||||
if ($opts.Contains($arg)) {
|
||||
$this._bitresolution = $this.Setter('bitresolution', $arg)
|
||||
}
|
||||
else {
|
||||
"bitresolution got: $arg, expected one of $opts" | Write-Warning
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
|
||||
{
|
||||
$this.Getter('channel')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
if ($arg -ge 1 -and $arg -le 8) {
|
||||
$this._channel = $this.Setter('channel', $arg)
|
||||
}
|
||||
else {
|
||||
"channel got: $arg, expected value from 1 to 8" | Write-Warning
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_kbps = $($this | Add-Member ScriptProperty 'kbps' `
|
||||
{
|
||||
$this.Getter('kbps')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
$opts = @(32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
|
||||
if ($opts.Contains($arg)) {
|
||||
$this._kbps = $this.Setter('kbps', $arg)
|
||||
}
|
||||
else {
|
||||
"kbps got: $arg, expected one of $opts" | Write-Warning
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
[void] Load ([string]$filename) {
|
||||
$this.Setter('load', $filename)
|
||||
}
|
||||
|
||||
[void] GoTo ([string]$timestring) {
|
||||
try {
|
||||
if ([datetime]::ParseExact($timestring, "HH:mm:ss", $null)) {
|
||||
$timespan = [timespan]::Parse($timestring)
|
||||
$this.Setter("GoTo", $timespan.TotalSeconds)
|
||||
}
|
||||
}
|
||||
catch [FormatException] {
|
||||
"Time string $timestring does not match the required format 'hh:mm:ss'" | Write-Warning
|
||||
}
|
||||
}
|
||||
|
||||
[void] FileType($format) {
|
||||
[int]$val = 0
|
||||
switch ($format) {
|
||||
"wav" { $val = 1 }
|
||||
"aiff" { $val = 2 }
|
||||
"bwf" { $val = 3 }
|
||||
"mp3" { $val = 100 }
|
||||
default { "Filetype() got: $format, expected one of 'wav', 'aiff', 'bwf', 'mp3'" }
|
||||
}
|
||||
$this.Setter("filetype", $val)
|
||||
}
|
||||
}
|
||||
|
||||
class RecorderMode : IRecorder {
|
||||
RecorderMode ([Object]$remote) : base ($remote) {
|
||||
AddBoolMembers -PARAMS @('recbus', 'playonload', 'loop', 'multitrack')
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return "Recorder.Mode"
|
||||
}
|
||||
}
|
||||
|
||||
class RecorderArm : IRecorder {
|
||||
[int]$index
|
||||
|
||||
RecorderArm ([int]$index, [Object]$remote) : base ($remote) {
|
||||
$this.index = $index
|
||||
}
|
||||
|
||||
Set ([bool]$val) {
|
||||
$this.Setter("", $(if ($val) { 1 } else { 0 }))
|
||||
}
|
||||
}
|
||||
|
||||
class RecorderArmStrip : RecorderArm {
|
||||
RecorderArmStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return "Recorder.ArmStrip[$($this.index)]"
|
||||
}
|
||||
}
|
||||
|
||||
class RecorderArmBus : RecorderArm {
|
||||
RecorderArmBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return "Recorder.ArmBus[$($this.index)]"
|
||||
}
|
||||
}
|
||||
|
||||
function Make_Recorder ([Object]$remote) {
|
||||
|
||||
100
lib/strip.ps1
100
lib/strip.ps1
@@ -1,5 +1,3 @@
|
||||
. $PSScriptRoot\meta.ps1
|
||||
|
||||
class IStrip {
|
||||
[int]$index
|
||||
[Object]$remote
|
||||
@@ -14,19 +12,31 @@ class IStrip {
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
|
||||
$this.Cmd($param) | Write-Debug
|
||||
return $this.remote.Getter($this.Cmd($param))
|
||||
}
|
||||
|
||||
[string] Getter_String ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
|
||||
$this.Cmd($param) | Write-Debug
|
||||
return $this.remote.Getter_String($this.Cmd($param))
|
||||
}
|
||||
|
||||
[void] Setter ($param, $val) {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
|
||||
"$($this.Cmd($param))=$val" | Write-Debug
|
||||
$this.remote.Setter($this.Cmd($param), $val)
|
||||
}
|
||||
|
||||
[string] Cmd ($param) {
|
||||
if ([string]::IsNullOrEmpty($param)) {
|
||||
return $this.identifier()
|
||||
}
|
||||
return "$($this.identifier()).$param"
|
||||
}
|
||||
}
|
||||
|
||||
class Strip : IStrip {
|
||||
[Object]$levels
|
||||
|
||||
Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('mono', 'solo', 'mute')
|
||||
AddIntMembers -PARAMS @('limit')
|
||||
@@ -35,6 +45,8 @@ class Strip : IStrip {
|
||||
|
||||
AddChannelMembers
|
||||
AddGainlayerMembers
|
||||
|
||||
$this.levels = [StripLevels]::new($index, $remote)
|
||||
}
|
||||
|
||||
[string] ToString() {
|
||||
@@ -50,6 +62,52 @@ class Strip : IStrip {
|
||||
}
|
||||
}
|
||||
|
||||
class StripLevels : IStrip {
|
||||
[int]$init
|
||||
[int]$offset
|
||||
|
||||
StripLevels ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
$p_in = $remote.kind.p_in
|
||||
if ($index -lt $p_in) {
|
||||
$this.init = $index * 2
|
||||
$this.offset = 2
|
||||
}
|
||||
else {
|
||||
$this.init = ($p_in * 2) + (($index - $p_in) * 8)
|
||||
$this.offset = 8
|
||||
}
|
||||
}
|
||||
|
||||
[float] Convert([float]$val) {
|
||||
if ($val -gt 0) {
|
||||
return [math]::Round(20 * [math]::Log10($val), 1)
|
||||
}
|
||||
else {
|
||||
return -200.0
|
||||
}
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] Getter([int]$mode) {
|
||||
[System.Collections.ArrayList]$vals = @()
|
||||
$this.init..$($this.init + $this.offset - 1) | ForEach-Object {
|
||||
$vals.Add($this.Convert($(Get_Level -MODE $mode -INDEX $_)))
|
||||
}
|
||||
return $vals
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] PreFader() {
|
||||
return $this.Getter(0)
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] PostFader() {
|
||||
return $this.Getter(1)
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] PostMute() {
|
||||
return $this.Getter(2)
|
||||
}
|
||||
}
|
||||
|
||||
class PhysicalStrip : Strip {
|
||||
[Object]$comp
|
||||
[Object]$gate
|
||||
@@ -62,16 +120,16 @@ class PhysicalStrip : Strip {
|
||||
AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2')
|
||||
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)
|
||||
$this.comp = [StripComp]::new($index, $remote)
|
||||
$this.gate = [StripGate]::new($index, $remote)
|
||||
$this.denoiser = [StripDenoiser]::new($index, $remote)
|
||||
$this.eq = [StripEq]::new($index, $remote)
|
||||
$this.device = [StripDevice]::new($index, $remote)
|
||||
}
|
||||
}
|
||||
|
||||
class Comp : IStrip {
|
||||
Comp ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripComp : IStrip {
|
||||
StripComp ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
|
||||
AddBoolMembers -PARAMS @('makeup')
|
||||
}
|
||||
@@ -91,8 +149,8 @@ class Comp : IStrip {
|
||||
)
|
||||
}
|
||||
|
||||
class Gate : IStrip {
|
||||
Gate ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripGate : IStrip {
|
||||
StripGate ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
|
||||
}
|
||||
|
||||
@@ -111,8 +169,8 @@ class Gate : IStrip {
|
||||
)
|
||||
}
|
||||
|
||||
class Denoiser : IStrip {
|
||||
Denoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripDenoiser : IStrip {
|
||||
StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
@@ -130,8 +188,8 @@ class Denoiser : IStrip {
|
||||
)
|
||||
}
|
||||
|
||||
class Eq : IStrip {
|
||||
Eq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripEq : IStrip {
|
||||
StripEq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('on', 'ab')
|
||||
}
|
||||
|
||||
@@ -140,15 +198,15 @@ class Eq : IStrip {
|
||||
}
|
||||
}
|
||||
|
||||
class Device : IStrip {
|
||||
Device ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripDevice : IStrip {
|
||||
StripDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return "Strip[" + $this.index + "].Device"
|
||||
}
|
||||
|
||||
hidden $_device = $($this | Add-Member ScriptProperty 'device' `
|
||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
||||
{
|
||||
$this.Getter_String('name')
|
||||
} `
|
||||
|
||||
45
lib/vban.ps1
45
lib/vban.ps1
@@ -1,9 +1,11 @@
|
||||
class IVban {
|
||||
[int32]$index
|
||||
[Object]$remote
|
||||
[string]$direction
|
||||
|
||||
IVban ([int]$index, [string]$direction) {
|
||||
IVban ([int]$index, [Object]$remote, [string]$direction) {
|
||||
$this.index = $index
|
||||
$this.remote = $remote
|
||||
$this.direction = $direction
|
||||
}
|
||||
|
||||
@@ -11,25 +13,34 @@ class IVban {
|
||||
return "vban." + $this.direction + "stream[" + $this.index + "]"
|
||||
}
|
||||
|
||||
[string] ToString() {
|
||||
return $this.GetType().Name + $this.index
|
||||
}
|
||||
|
||||
[single] Getter ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $false
|
||||
return $this.remote.Getter($this.Cmd($param))
|
||||
}
|
||||
|
||||
[string] Getter_String ($param) {
|
||||
return Param_Get -PARAM "$($this.identifier()).$param" -IS_STRING $true
|
||||
$this.Cmd($param) | Write-Debug
|
||||
return $this.remote.Getter_String($this.Cmd($param))
|
||||
}
|
||||
|
||||
[void] Setter ($param, $val) {
|
||||
Param_Set -PARAM "$($this.identifier()).$param" -Value $val
|
||||
"$($this.Cmd($param))=$val" | Write-Debug
|
||||
$this.remote.Setter($this.Cmd($param), $val)
|
||||
}
|
||||
|
||||
[string] Cmd ($param) {
|
||||
if ([string]::IsNullOrEmpty($param)) {
|
||||
return $this.identifier()
|
||||
}
|
||||
return "$($this.identifier()).$param"
|
||||
}
|
||||
}
|
||||
|
||||
class Vban : IVban {
|
||||
Vban ([int]$index, [string]$direction) : base ($index, $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' `
|
||||
@@ -68,7 +79,7 @@ class Vban : IVban {
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
if ($arg -in 1024..65535) {
|
||||
if ($arg -ge 1024 -and $arg -le 65535) {
|
||||
$this._port = $this.Setter('port', $arg)
|
||||
}
|
||||
else {
|
||||
@@ -104,7 +115,7 @@ class Vban : IVban {
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
if ($arg -in 1..8) {
|
||||
if ($arg -ge 1 -and $arg -le 8) {
|
||||
$this._channel = $this.Setter('channel', $arg)
|
||||
}
|
||||
else {
|
||||
@@ -142,7 +153,7 @@ class Vban : IVban {
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
if ($arg -in 0..4) {
|
||||
if ($arg -ge 0 -and $arg -le 4) {
|
||||
$this._quality = $this.Setter('quality', $arg)
|
||||
}
|
||||
else {
|
||||
@@ -160,7 +171,7 @@ class Vban : IVban {
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
if ($arg -in 0..8) {
|
||||
if ($arg -ge 0 -and $arg -le 8) {
|
||||
$this._route = $this.Setter('route', $arg)
|
||||
}
|
||||
else {
|
||||
@@ -173,13 +184,13 @@ class Vban : IVban {
|
||||
|
||||
|
||||
class VbanInstream : Vban {
|
||||
VbanInstream ([int]$index, [string]$direction) : base ($index, $direction) {
|
||||
VbanInstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VbanOutstream : Vban {
|
||||
VbanOutstream ([int]$index, [string]$direction) : base ($index, $direction) {
|
||||
VbanOutstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,10 +200,10 @@ function Make_Vban ([Object]$remote) {
|
||||
[System.Collections.ArrayList]$outstream = @()
|
||||
|
||||
0..$($remote.kind.vban_in - 1) | ForEach-Object {
|
||||
[void]$instream.Add([VbanInstream]::new($_, "in"))
|
||||
[void]$instream.Add([VbanInstream]::new($_, $remote, "in"))
|
||||
}
|
||||
0..$($remote.kind.vban_out - 1) | ForEach-Object {
|
||||
[void]$outstream.Add([VbanOutstream]::new($_, "out"))
|
||||
[void]$outstream.Add([VbanOutstream]::new($_, $remote, "out"))
|
||||
}
|
||||
|
||||
$CustomObject = [pscustomobject]@{
|
||||
|
||||
@@ -34,6 +34,7 @@ Function ParseLog {
|
||||
function main() {
|
||||
try {
|
||||
$vmr = Connect-Voicemeeter -Kind $kind
|
||||
$vmr.command.RunMacrobuttons() # ensure macrobuttons is running before we begin
|
||||
Write-Host "Running tests for $vmr"
|
||||
|
||||
# test boundaries by kind
|
||||
@@ -72,5 +73,4 @@ function main() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($MyInvocation.InvocationName -ne '.') { main }
|
||||
main
|
||||
|
||||
Reference in New Issue
Block a user