mirror of
https://github.com/onyx-and-iris/voicemeeter-api-powershell.git
synced 2026-04-20 06:23:32 +00:00
Compare commits
166 Commits
add-record
...
6542473394
| Author | SHA1 | Date | |
|---|---|---|---|
| 6542473394 | |||
| 448aa01ad2 | |||
| dfa044d853 | |||
| 21eab2e528 | |||
| 8679b4199f | |||
|
|
c64d81c36f | ||
|
|
797ab2e597 | ||
|
|
55eb851729 | ||
|
|
ef1a583351 | ||
|
|
0d303e20be | ||
|
|
c446ad8c93 | ||
| f5bdeb6d57 | |||
| be58d6a9e5 | |||
| eb3af982da | |||
| 83c81384be | |||
| e848037b30 | |||
|
|
66b3fb355c | ||
|
|
30da69469b | ||
|
|
59f3168436 | ||
|
|
b273aa7a51 | ||
| b128ee0625 | |||
|
|
9d3f58f6f2 | ||
|
|
ea6192ba5f | ||
|
|
ea780f6595 | ||
|
|
126e6172cb | ||
|
|
0c60c5e6c5 | ||
| 837211424f | |||
| 88901aa6ee | |||
|
|
64ebc86f21 | ||
|
|
8855092438 | ||
|
|
865d094450 | ||
|
|
1cdbf9e272 | ||
|
|
23b86fecb9 | ||
|
|
61b3ecd3d3 | ||
|
|
a2b75fa21b | ||
|
|
618f4a8462 | ||
|
|
a22dccf18f | ||
|
|
64e6874a75 | ||
|
|
ac3e36838e | ||
|
|
a5bade4fbb | ||
|
|
2cf265b3b6 | ||
|
|
0bdfb1c38f | ||
|
|
4189ac7721 | ||
|
|
6d511d8aa6 | ||
| 46584236d4 | |||
| a8e66113f7 | |||
|
|
daa1fa6c13 | ||
|
|
bc136d870b | ||
|
|
8f49403555 | ||
|
|
dd38cf4bc2 | ||
| 771238b3b6 | |||
| 1ad91b455a | |||
|
|
1310ca25ef | ||
|
|
cfa7de9b11 | ||
|
|
b5546aa56c | ||
| 77a8792377 | |||
|
|
df86ad2175 | ||
|
|
1d41be7396 | ||
|
|
ab4baa5c44 | ||
|
|
e42862c32d | ||
|
|
0564dce7b6 | ||
|
|
8c3217b9a8 | ||
|
|
d7cb1d610d | ||
|
|
58652b5a3f | ||
|
|
9209bbbc65 | ||
| f40e0afb0d | |||
|
|
bef4e64c9e | ||
|
|
9b1b78100c | ||
|
|
dd31bfcc55 | ||
|
|
0fbd41ac0b | ||
| df2d1bb156 | |||
|
|
6e74db2751 | ||
|
|
5f064de010 | ||
|
|
dd404ae337 | ||
| 68f582512a | |||
|
|
8f5536f139 | ||
|
|
7eb82c41a2 | ||
|
|
ec05790312 | ||
|
|
2def27573d | ||
|
|
36d4e5f6c4 | ||
| e944dc46e6 | |||
|
|
d87cdbd444 | ||
|
|
06942a234d | ||
|
|
17e601a8d6 | ||
|
|
72185d14b3 | ||
|
|
81764f0e43 | ||
|
|
90e9dcd06c | ||
| b92a2422a7 | |||
|
|
2eecdd7def | ||
| 5c623711f7 | |||
|
|
8d97df2d92 | ||
|
|
438fa525da | ||
|
|
aa2c2a24af | ||
|
|
d3e9ad2bf4 | ||
| abdf2dbf5d | |||
|
|
02bc174746 | ||
|
|
8038fc24ce | ||
|
|
d13b08eff4 | ||
|
|
dedb4201be | ||
|
|
60d97a89b4 | ||
|
|
6154af7ad7 | ||
| 07028478cc | |||
|
|
3f7bef56c1 | ||
|
|
820b897e84 | ||
|
|
1e4a2da821 | ||
|
|
ee85d5ffd8 | ||
| b20f62f17c | |||
|
|
1587b2ea6a | ||
|
|
88468d4e52 | ||
|
|
a69902ec49 | ||
|
|
10c85cead5 | ||
|
|
d81cd32392 | ||
|
|
e887e15168 | ||
|
|
c5a8813e9a | ||
| 16dd73231e | |||
|
|
15a977834d | ||
|
|
f3ed1de557 | ||
|
|
54319924d0 | ||
| 4d54e0a15f | |||
|
|
dce6f37bf1 | ||
|
|
5fc5680c75 | ||
|
|
80869d4306 | ||
|
|
e0b01288ff | ||
|
|
3a5c7286f6 | ||
|
|
c086f58ade | ||
|
|
e5137b842b | ||
|
|
78f7fc80d4 | ||
|
|
62d9e89b5f | ||
|
|
a6f7d8efe0 | ||
|
|
b372cf8087 | ||
|
|
eeb30925fa | ||
|
|
09d8bd48eb | ||
|
|
b0a6bf7b63 | ||
|
|
9a2529c617 | ||
|
|
2404bfb50f | ||
| bd0779add2 | |||
| a0a2c72634 | |||
| 0f68a2373d | |||
| 2d6437d37b | |||
| f199fa587f | |||
| b6c9c65390 | |||
| 436b47a5db | |||
| 0cdd71600f | |||
| 41529c0d58 | |||
| b1a6ac68c1 | |||
| fbfab5b4aa | |||
| 4d371a7582 | |||
| 15b3b375bd | |||
| c8abc6964a | |||
| 907ee3e63b | |||
| f3ed9c28c7 | |||
| d305a4048d | |||
| 108731b4cf | |||
| e7c648f1d0 | |||
| b21a71471b | |||
| 43367525c5 | |||
| d0fbd6deef | |||
| 1df92afcfe | |||
| 2ad8118f2c | |||
| bc6162cf16 | |||
| 9b3d9f2250 | |||
| 844eaeabaa | |||
| a78cdf9a99 | |||
| a40adf27be | |||
| 1397c14522 | |||
| ff1bd5e6cc |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
# quick test
|
|
||||||
quick.ps1
|
|
||||||
|
|
||||||
lib/*.psd1
|
lib/*.psd1
|
||||||
**/*.log
|
**/*.log
|
||||||
|
|
||||||
config.psd1
|
config.psd1
|
||||||
|
|
||||||
|
test-*.ps1
|
||||||
28
.vscode/launch.json
vendored
28
.vscode/launch.json
vendored
@@ -16,7 +16,9 @@
|
|||||||
"\"!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
|
||||||
},
|
},
|
||||||
@@ -26,7 +28,10 @@
|
|||||||
"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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -35,7 +40,10 @@
|
|||||||
"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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -43,21 +51,9 @@
|
|||||||
"type": "PowerShell",
|
"type": "PowerShell",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"script": "${workspaceFolder}/tests/pre-commit.ps1",
|
"script": "${workspaceFolder}/tests/run.ps1",
|
||||||
"args": [],
|
"args": [],
|
||||||
"createTemporaryIntegratedConsole": true
|
"createTemporaryIntegratedConsole": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "PowerShell: Launch Quick Test",
|
|
||||||
"type": "PowerShell",
|
|
||||||
"request": "launch",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"script": "${workspaceFolder}/quick.ps1",
|
|
||||||
"args": [
|
|
||||||
"-Verbose",
|
|
||||||
"-Debug"
|
|
||||||
],
|
|
||||||
"createTemporaryIntegratedConsole": true
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
168
CHANGELOG.md
168
CHANGELOG.md
@@ -5,14 +5,174 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
Before any major/minor/patch is released all test units will be run to verify they pass.
|
Before any major/minor/patch is released all unit tests will be run to verify they pass.
|
||||||
|
|
||||||
## [Unreleased] These changes have not been added to PSGallery yet
|
## [Unreleased] These changes have not been added to PSGallery yet
|
||||||
|
|
||||||
- [x] Level methods for Strip,Bus classes implemented.
|
|
||||||
- [x] More Recorder commands implemented.
|
|
||||||
|
|
||||||
## [3.0.0]
|
## [4.1.0] - 2025-12-23
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Bus.EQ.Channel.Trim
|
||||||
|
- Bus.EQ.Channel.Delay
|
||||||
|
|
||||||
|
- MIDI Vban.Outstream.Route: 'none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out'
|
||||||
|
- Video Vban.Outstream
|
||||||
|
- Vban.Outstream.Vfps
|
||||||
|
- Vban.Outstream.Vformat: 'png', 'jpg'
|
||||||
|
- Vban.Outstream.Vquality
|
||||||
|
- Vban.Outstream.Vcursor
|
||||||
|
- Vban.Outstream.Route (VMR bug: currently write-only)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `on`, `name`, `ip` now read/write on all streams
|
||||||
|
- Simple ranges of consecutive integers moved to `AddIntMembers`
|
||||||
|
- Retained warning for `sr` and anything with atypical behavior, consistent with the rest of the module
|
||||||
|
- Retained warning for `port` because Voicemeeter will allow this to be set below 1024
|
||||||
|
- Audio instream/outstream divergent behavior via 'if' dropped in favor of explicit separation in derived classes
|
||||||
|
|
||||||
|
- Updated EQ.Channel.Cell.Gain range in README
|
||||||
|
|
||||||
|
## [4.0.0] - 2025-12-16
|
||||||
|
|
||||||
|
This release introduces some breaking changes, the affected classes are Command, Recorder and Strip.
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
|
||||||
|
- Some of the Command properties have been converted to methods. See Command section in README for more details.
|
||||||
|
- Recorder.loop removed, it can be accessed through {Recorder}.{Mode}.loop.
|
||||||
|
- Recorder.FileType changed from method to write-only property.
|
||||||
|
- Strip Gainlayers are now defined by their own class and may be accessed through {Strip}.Gainlayer[i].
|
||||||
|
- The previous {Strip}.gainlayer{i} properties have been removed.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Meta functions can now take a -ReadOnly or -WriteOnly switch parameter
|
||||||
|
- Meta: AddBoolMembers, AddIntMembers $arg types for consistency
|
||||||
|
- Float getters/setters now default to two decimal places.
|
||||||
|
- Device: explicit $arg types for consistency
|
||||||
|
- Device members now added with meta functions
|
||||||
|
|
||||||
|
- some vban.instream | vban.outstream commands now added with meta functions
|
||||||
|
- on
|
||||||
|
- name
|
||||||
|
- ip
|
||||||
|
- cast vban getters to types for consistency
|
||||||
|
|
||||||
|
- Recorder.Armstrip|Armbus -> BoolArrayMember: now have .Get()
|
||||||
|
- Cast Recorder getters to types for consistency
|
||||||
|
- Recorder.Prefix now added with AddStringMembers
|
||||||
|
|
||||||
|
- Strip.Mono is now an alias for Strip.MC on virtual strips
|
||||||
|
- Strip.AppMute|AppGain can now take an app index; see README for details
|
||||||
|
- Strip Knob setters: explicit $arg types for consistency
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- IRemote abstract base class serves as a launching point for the higher classes.
|
||||||
|
- ArrayMember classes offer a common interface for array-like properties
|
||||||
|
- Patch class
|
||||||
|
- Option class
|
||||||
|
- IO classes to centralize controls common to both Strip and Bus
|
||||||
|
- IOControl
|
||||||
|
- IOLevels
|
||||||
|
- IOEq
|
||||||
|
- IODevice
|
||||||
|
- FX class
|
||||||
|
|
||||||
|
- AddAliasMembers meta function takes a hashtable `-MAP` of `alias = property`
|
||||||
|
|
||||||
|
- Vban.port sets Vban.Instream[0].port
|
||||||
|
- Vban Midi and Command streams
|
||||||
|
- on, write-only
|
||||||
|
- name, write-only
|
||||||
|
- ip, write-only
|
||||||
|
|
||||||
|
- Recorder.Armedbus
|
||||||
|
- Recorder.PreRecTime
|
||||||
|
- Recorder.Prefix
|
||||||
|
- Recorder.State
|
||||||
|
- Recorder.Eject()
|
||||||
|
|
||||||
|
- Command.Reset()
|
||||||
|
- Command.Save($filepath)
|
||||||
|
- Command.StorePreset()
|
||||||
|
- Command.RecallPreset()
|
||||||
|
|
||||||
|
- Bus.Sel, Bus.Monitor, Bus.Vaio
|
||||||
|
- Bus.Mode.Set($mode)
|
||||||
|
|
||||||
|
- Strip.Karaoke alias for Strip.K
|
||||||
|
- Strip.EQGain1|EQGain2|EQGain3 with bass/low, mid/med, treble/high aliases, respectively
|
||||||
|
- StripKnob base class which defines a knob property.
|
||||||
|
- StripAudbility class which represents the audibility knob for basic kind, it subclasses StripKnob.
|
||||||
|
- Strip.Denoiser.Threshold
|
||||||
|
- Strip.VAIO.
|
||||||
|
- Strip.Pitch, StripPitch class
|
||||||
|
- on
|
||||||
|
- drywet
|
||||||
|
- pitchvalue
|
||||||
|
- loformant
|
||||||
|
- medformant
|
||||||
|
- hiformant
|
||||||
|
- recallpreset($presetIndex)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- some vban commands incorrectly read-only/write-only
|
||||||
|
- enable
|
||||||
|
- instream|outstream.quality
|
||||||
|
- instream|outstream.route
|
||||||
|
- vban.stream.port: [string]$arg -> [int]$arg
|
||||||
|
- vban route range (API documentation is incorrect)
|
||||||
|
- vban.stream.sr: $this._port -> $this._sr
|
||||||
|
|
||||||
|
- Recorder.channel values: 1..8 -> (2, 4, 6, 8)
|
||||||
|
|
||||||
|
- Bus.Mono -> [int]
|
||||||
|
- This gives the user access to set stereo reverse.
|
||||||
|
|
||||||
|
- Strip.Limit type [int] -> [float]
|
||||||
|
- Missing closing parenthesis in AppMute value string
|
||||||
|
- Strip Knob getters: `this.Getter_String('') -> [math]::Round($this.Getter(''), 2)`
|
||||||
|
|
||||||
|
## [3.3.0] - 2024-06-29
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add a timeout (2s) to the login function. If timeout exceeded a VMRemoteError is thrown.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Launch x64 bit GUIs for all kinds if on 64 bit system.
|
||||||
|
|
||||||
|
## [3.2.0] - 2023-08-17
|
||||||
|
|
||||||
|
### 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 [VMRemoteError] if script length exceeds 48kB.
|
||||||
|
- parameter range checks in Vban class.
|
||||||
|
|
||||||
|
## [3.1.0] - 2023-08-15
|
||||||
|
|
||||||
|
### 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] - 2023-08-09
|
||||||
|
|
||||||
v3 introduces some breaking changes. They are as follows:
|
v3 introduces some breaking changes. They are as follows:
|
||||||
|
|
||||||
|
|||||||
596
README.md
596
README.md
@@ -8,9 +8,9 @@ For past/future changes to this project refer to: [CHANGELOG](CHANGELOG.md)
|
|||||||
|
|
||||||
## Tested against
|
## Tested against
|
||||||
|
|
||||||
- Basic 1.0.8.8
|
- Basic 1.1.2.2
|
||||||
- Banana 2.0.6.8
|
- Banana 2.1.2.2
|
||||||
- Potato 3.0.2.8
|
- Potato 3.1.2.2
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -113,59 +113,77 @@ $vmr.Logout()
|
|||||||
|
|
||||||
### Strip
|
### Strip
|
||||||
|
|
||||||
The following strip commands are available:
|
The following Strip properties are available:
|
||||||
|
|
||||||
- mute: boolean
|
- mute: bool
|
||||||
- mono: boolean
|
- mono: bool
|
||||||
- mc: boolean
|
- mc: bool
|
||||||
- k: int, from 0 to 4
|
- k/karaoke: int, from 0 to 4
|
||||||
- solo: boolean
|
- solo: bool
|
||||||
- A1-A5: boolean
|
- A1-A5: bool
|
||||||
- B1-B3: boolean
|
- B1-B3: bool
|
||||||
- limit: int, from -40 to 12
|
- vaio: bool
|
||||||
- gain: float, from -60.0 to 12.0
|
- limit: float, from -40.00 to 12.00
|
||||||
|
- gain: float, from -60.00 to 12.00
|
||||||
- label: string
|
- label: string
|
||||||
- reverb: float, from 0.0 to 10.0
|
- reverb: float, from 0.00 to 10.00
|
||||||
- delay: float, from 0.0 to 10.0
|
- delay: float, from 0.00 to 10.00
|
||||||
- fx1: float, from 0.0 to 10.0
|
- fx1: float, from 0.00 to 10.00
|
||||||
- fx2: float, from 0.0 to 10.0
|
- fx2: float, from 0.00 to 10.00
|
||||||
- pan_x: float, from -0.5 to 0.5
|
- pan_x: float, from -0.50 to 0.50
|
||||||
- pan_y: float, from 0.0 to 1.0
|
- pan_y: float, physical: from 0.00 to 1.00, virtual: from -0.50 to 0.50
|
||||||
- color_x: float, from -0.5 to 0.5
|
- color_x: float, from -0.50 to 0.50
|
||||||
- color_y: float, from 0.0 to 1.0
|
- color_y: float, from 0.00 to 1.00
|
||||||
- fx_x: float, from -0.5 to 0.5
|
- fx_x: float, from -0.50 to 0.50
|
||||||
- fx_y: float, from 0.0 to 1.0
|
- fx_y: float, from 0.00 to 1.00
|
||||||
- postreverb: boolean
|
- postreverb: bool
|
||||||
- postdelay: boolean
|
- postdelay: bool
|
||||||
- postfx1: boolean
|
- postfx1: bool
|
||||||
- postfx2: boolean
|
- postfx2: bool
|
||||||
- gainlayer0-gainlayer7: float
|
- eqgain1/bass/low: float, from -12.00 to 12.00
|
||||||
|
- eqgain2/mid/med: float, from -12.00 to 12.00
|
||||||
|
- eqgain3/treble/high: float, from -12.00 to 12.00
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.strip[5].gainlayer1 = -8.3
|
$vmr.strip[6].karaoke = 3
|
||||||
|
$vmr.strip[0].limit = 4.5
|
||||||
|
$vmr.strip[2].label = 'example'
|
||||||
|
$vmr.strip[7].pan_y = -0.38
|
||||||
|
$vmr.strip[5].treble = -2.43
|
||||||
```
|
```
|
||||||
|
|
||||||
A,B commands depend on Voicemeeter type.
|
The following Strip methods are available:
|
||||||
|
|
||||||
gainlayers defined for Potato version only.
|
- AppGain($appname or $appindex, $gain) : string or int, float, from 0.00 to 1.00
|
||||||
|
- AppMute($appname or $appindex, $mutestate) : string or int, bool
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[5].AppGain("Spotify", 0.5)
|
||||||
|
$vmr.strip[5].AppMute("Spotify", $true)
|
||||||
|
$vmr.strip[7].AppGain(0, 0.28)
|
||||||
|
$vmr.strip[6].AppMute(2, $false)
|
||||||
|
```
|
||||||
|
|
||||||
|
A,B properties depend on Voicemeeter type.
|
||||||
mc, k for virtual strips only.
|
mc, k for virtual strips only.
|
||||||
|
|
||||||
#### comp
|
#### comp
|
||||||
|
|
||||||
The following strip.comp commands are available:
|
The following Strip.comp properties are available:
|
||||||
|
|
||||||
- knob: float, from 0.0 to 10.0
|
- knob: float, from 0.00 to 10.00
|
||||||
- gainin: float, from -24.0 to 24.0
|
- gainin: float, from -24.00 to 24.00
|
||||||
- ratio: float, from 1.0 to 8.0
|
- ratio: float, from 1.00 to 8.00
|
||||||
- threshold: float, from -40.0 to -3.0
|
- threshold: float, from -40.00 to -3.00
|
||||||
- attack: float, from 0.0 to 200.0
|
- attack: float, from 0.00 to 200.00
|
||||||
- release: float, from 0.0 to 5000.0
|
- release: float, from 0.00 to 5000.00
|
||||||
- knee: float, 0.0 to 1.0
|
- knee: float, 0.00 to 1.00
|
||||||
- gainout: float, from -24.0 to 24.0
|
- gainout: float, from -24.00 to 24.00
|
||||||
- makeup: boolean
|
- makeup: bool
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
@@ -175,15 +193,15 @@ $vmr.strip[3].comp.attack = 8.5
|
|||||||
|
|
||||||
#### gate
|
#### gate
|
||||||
|
|
||||||
The following strip.gate commands are available:
|
The following Strip.gate properties are available:
|
||||||
|
|
||||||
- knob: float, from 0.0 to 10.0
|
- knob: float, from 0.00 to 10.00
|
||||||
- threshold: float, from -60.0 to -10.0
|
- threshold: float, from -60.00 to -10.00
|
||||||
- damping: float, from -60.0 to -10.0
|
- damping: float, from -60.00 to -10.00
|
||||||
- bpsidechain: int, from 100 to 4000
|
- bpsidechain: float, from 100.00 to 4000.00
|
||||||
- attack: float, from 0.0 to 1000.0
|
- attack: float, from 0.00 to 1000.00
|
||||||
- hold: float, from 0.0 to 5000.0
|
- hold: float, from 0.00 to 5000.00
|
||||||
- release: float, from 0.0 to 5000.0
|
- release: float, from 0.00 to 5000.00
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
@@ -193,9 +211,10 @@ $vmr.strip[3].gate.threshold = -40.5
|
|||||||
|
|
||||||
#### denoiser
|
#### denoiser
|
||||||
|
|
||||||
The following strip.denoiser commands are available:
|
The following Strip.denoiser properties are available:
|
||||||
|
|
||||||
- knob: float, from 0.0 to 10.0
|
- knob: float, from 0.00 to 10.00
|
||||||
|
- threshold: float, from 0.00 to 10.00
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
@@ -203,21 +222,57 @@ for example:
|
|||||||
$vmr.strip[3].denoiser.knob = 5
|
$vmr.strip[3].denoiser.knob = 5
|
||||||
```
|
```
|
||||||
|
|
||||||
#### AppGain | AppMute
|
#### pitch
|
||||||
|
|
||||||
- `AppGain(amount, gain)` : string, float
|
The following Strip.pitch properties are available:
|
||||||
- `AppMute(amount, mutestate)` : string, boolean
|
|
||||||
|
- on: bool
|
||||||
|
- drywet: float, from -100.00 to 100.00
|
||||||
|
- pitchvalue: float, from -12.00 to 12.00
|
||||||
|
- loformant: float, from -12.00 to 12.00
|
||||||
|
- medformant: float, from -12.00 to 12.00
|
||||||
|
- hiformant: float, from -12.00 to 12.00
|
||||||
|
|
||||||
|
The following Strip.pitch methods are available:
|
||||||
|
|
||||||
|
- RecallPreset($presetIndex) : int, from 0 to 7
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.strip[5].AppGain("Spotify", 0.5)
|
$vmr.strip[2].pitch.recallpreset(4)
|
||||||
$vmr.strip[5].AppMute("Spotify", $true)
|
$vmr.strip[4].pitch.drywet = -22.86
|
||||||
|
$vmr.strip[1].pitch.medformant = 2.1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### audibility
|
||||||
|
|
||||||
|
The following Strip.audibility properties are available:
|
||||||
|
|
||||||
|
- knob: float, from 0.00 to 10.00
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[1].audibility.knob = 2.66
|
||||||
|
```
|
||||||
|
|
||||||
|
#### gainlayer[i]
|
||||||
|
|
||||||
|
The following Strip.gainlayer[i] methods are available:
|
||||||
|
|
||||||
|
- Set($val) : float, from -60.00 to 12.00
|
||||||
|
- Get()
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[4].gainlayer[7].set(-26.81)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### levels
|
#### levels
|
||||||
|
|
||||||
The following strip.level commands are available:
|
The following Strip.levels methods are available:
|
||||||
|
|
||||||
- PreFader()
|
- PreFader()
|
||||||
- PostFader()
|
- PostFader()
|
||||||
@@ -231,17 +286,19 @@ $vmr.strip[2].levels.PreFader() -Join ', ' | Write-Host
|
|||||||
|
|
||||||
### Bus
|
### Bus
|
||||||
|
|
||||||
The following bus commands are available:
|
The following Bus properties are available:
|
||||||
|
|
||||||
- mute: bool
|
- mute: bool
|
||||||
- mono: bool
|
- sel: bool
|
||||||
- limit: int, from -40 to 12
|
- monitor: bool
|
||||||
- gain: float, from -60.0 to 12.0
|
- vaio: bool
|
||||||
|
- mono: int, 0 off, 1 mono, 2 stereo reverse
|
||||||
|
- gain: float, from -60.00 to 12.00
|
||||||
- label: string
|
- label: string
|
||||||
- returnreverb: float, from 0.0 to 10.0
|
- returnreverb: float, from 0.00 to 10.00
|
||||||
- returndelay: float, from 0.0 to 10.0
|
- returndelay: float, from 0.00 to 10.00
|
||||||
- returnfx1: float, from 0.0 to 10.0
|
- returnfx1: float, from 0.00 to 10.00
|
||||||
- returnfx2: float, from 0.0 to 10.0
|
- returnfx2: float, from 0.00 to 10.00
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
@@ -251,36 +308,36 @@ $vmr.bus[3].returnreverb = 5.7
|
|||||||
|
|
||||||
#### modes
|
#### modes
|
||||||
|
|
||||||
The following bus.mode members are available:
|
The following Bus.mode members are available:
|
||||||
|
|
||||||
- normal: boolean
|
- normal: bool
|
||||||
- amix: boolean
|
- amix: bool
|
||||||
- bmix: boolean
|
- bmix: bool
|
||||||
- repeat: boolean
|
- repeat: bool
|
||||||
- composite: boolean
|
- composite: bool
|
||||||
- tvmix: boolean
|
- tvmix: bool
|
||||||
- upmix21: boolean
|
- upmix21: bool
|
||||||
- upmix41: boolean
|
- upmix41: bool
|
||||||
- upmix61: boolean
|
- upmix61: bool
|
||||||
- centeronly: boolean
|
- centeronly: bool
|
||||||
- lfeonly: boolean
|
- lfeonly: bool
|
||||||
- rearonly: boolean
|
- rearonly: bool
|
||||||
|
|
||||||
The following bus.mode commands are available:
|
The following Bus.mode methods are available:
|
||||||
|
|
||||||
- Get(): returns the current bus mode.
|
- Set($mode) : string, sets the current bus mode
|
||||||
|
- Get() : returns the current bus mode
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.bus[0].mode.centeronly = $true
|
$vmr.bus[0].mode.centeronly = $true
|
||||||
|
$vmr.bus[0].mode.Set('tvmix')
|
||||||
$vmr.bus[0].mode.Get()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### levels
|
#### levels
|
||||||
|
|
||||||
The following strip.level commands are available:
|
The following Bus.levels methods are available:
|
||||||
|
|
||||||
- All()
|
- All()
|
||||||
|
|
||||||
@@ -292,9 +349,23 @@ $vmr.bus[2].levels.All() -Join ', ' | Write-Host
|
|||||||
|
|
||||||
### Strip|Bus
|
### Strip|Bus
|
||||||
|
|
||||||
|
The following Strip | Bus methods are available:
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[3].FadeTo(-18.75, 1000)
|
||||||
|
$vmr.bus[0].FadeBy(-10, 500)
|
||||||
|
```
|
||||||
|
|
||||||
#### device
|
#### device
|
||||||
|
|
||||||
The following strip.device | bus.device commands are available:
|
The following Strip.device | Bus.device properties are available:
|
||||||
|
|
||||||
- name: string
|
- name: string
|
||||||
- sr: int
|
- sr: int
|
||||||
@@ -307,18 +378,24 @@ for example:
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.strip[0].device.wdm = "Mic|Line|Instrument 1 (Audient EVO4)"
|
$vmr.strip[0].device.wdm = "Mic|Line|Instrument 1 (Audient EVO4)"
|
||||||
$vmr.bus[0].device.name
|
$vmr.bus[0].device.name | Write-Host
|
||||||
```
|
```
|
||||||
|
|
||||||
name, sr are defined as read only.
|
name, sr are defined as read only.
|
||||||
wdm, ks, mme, asio are defined as write only.
|
wdm, ks, mme, asio are defined as write only.
|
||||||
|
asio only defined for Bus[0].Device
|
||||||
|
|
||||||
#### eq
|
#### eq
|
||||||
|
|
||||||
The following strip.eq | bus.eq commands are available:
|
The following Strip.eq | Bus.eq properties are available:
|
||||||
|
|
||||||
- on: boolean
|
- on: bool
|
||||||
- ab: boolean
|
- ab: bool
|
||||||
|
|
||||||
|
The following Strip.eq | Bus.eq methods are available:
|
||||||
|
|
||||||
|
- Load($filepath) : string
|
||||||
|
- Save($filepath) : string
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
@@ -327,146 +404,320 @@ $vmr.strip[0].eq.on = $true
|
|||||||
$vmr.bus[0].eq.ab = $false
|
$vmr.bus[0].eq.ab = $false
|
||||||
```
|
```
|
||||||
|
|
||||||
#### FadeTo | FadeBy
|
##### channel
|
||||||
|
|
||||||
- `FadeTo(amount, time)` : float, int
|
The following bus.eq.channel.cell properties are available:
|
||||||
- `FadeBy(amount, time)` : float, int
|
|
||||||
|
|
||||||
Modify gain to or by the selected amount in db over a time interval in ms.
|
- trim: float, from -24.00 to 24.00
|
||||||
|
- delay: float, from 0.00 to 500.00
|
||||||
|
|
||||||
|
###### cell
|
||||||
|
|
||||||
|
The following eq.channel.cell properties are available:
|
||||||
|
|
||||||
|
- on: bool
|
||||||
|
- type: int, from 0 to 6
|
||||||
|
- f: float, from 20.00 to 20000.00
|
||||||
|
- gain: float, from -36.00 to 18.00
|
||||||
|
- q: float, from 0.30 to 100.00
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.strip[3].FadeTo(-18.7, 1000)
|
$vmr.strip[2].eq.channel[1].cell[4].type = 1
|
||||||
$vmr.bus[0].FadeBy(-10, 500)
|
$vmr.bus[5].eq.channel[6].cell[3].on = $false
|
||||||
```
|
```
|
||||||
|
|
||||||
### Macrobuttons
|
### Macrobuttons
|
||||||
|
|
||||||
Three modes defined: state, stateonly and trigger.
|
The following Button properties are available:
|
||||||
|
|
||||||
- State runs associated scripts
|
- state: bool, runs associated scripts
|
||||||
- Stateonly does not run associated scripts
|
- stateonly: bool, does not run associated scripts
|
||||||
- Index range (0, 69)
|
- trigger: bool
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.button[3].state = $true
|
$vmr.button[3].state = $true
|
||||||
|
|
||||||
$vmr.button[4].stateonly = $false
|
$vmr.button[4].stateonly = $false
|
||||||
|
|
||||||
$vmr.button[5].trigger = $true
|
$vmr.button[5].trigger = $true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Index range (0, 79)
|
||||||
|
|
||||||
### VBAN
|
### VBAN
|
||||||
|
|
||||||
- vmr.vban.enable: Toggle VBAN on or off. Accepts a boolean value.
|
The following Vban properties are available:
|
||||||
|
|
||||||
For each vban in/out stream the following parameters are defined:
|
- enable: bool
|
||||||
|
- port: int, from 1024 - 65535
|
||||||
|
|
||||||
- on: boolean
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.vban.enable = $true
|
||||||
|
$vmr.vban.port = 6990
|
||||||
|
```
|
||||||
|
|
||||||
|
#### instream[i]|outstream[i]
|
||||||
|
|
||||||
|
The following Vban.instream | Vban.outstream properties are available:
|
||||||
|
|
||||||
|
- on: bool
|
||||||
- name: string
|
- name: string
|
||||||
- ip: string
|
- ip: string
|
||||||
- port: int from 1024 - 65535
|
|
||||||
- sr: int (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
for example:
|
||||||
- channel: int from 1 to 8
|
|
||||||
- bit: int 16 or 24
|
```powershell
|
||||||
- quality: int from 0 to 4
|
$vmr.vban.instream[0].on = $true
|
||||||
- route: int from 0 to 8
|
$vmr.vban.outstream[9].ip = '192.168.1.154'
|
||||||
|
```
|
||||||
|
|
||||||
|
##### audio
|
||||||
|
|
||||||
|
The following audio Vban.instream | Vban.outstream properties are available:
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.vban.enable = $true
|
$vmr.vban.instream[0].route = 4
|
||||||
|
|
||||||
$vmr.vban.instream[0].on = $true
|
|
||||||
$vmr.vban.instream[2].port = 6990
|
|
||||||
$vmr.vban.outstream[3].bit = 16
|
$vmr.vban.outstream[3].bit = 16
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### midi
|
||||||
|
|
||||||
|
The following midi Vban.outstream properties are available:
|
||||||
|
|
||||||
|
- route: string, ('none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out')
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.vban.outstream[8].route = 'aux_in'
|
||||||
|
```
|
||||||
|
|
||||||
|
##### video
|
||||||
|
|
||||||
|
The following video Vban.outstream properties are available:
|
||||||
|
|
||||||
|
- vfps: int, from 1 to 30
|
||||||
|
- vformat: string, ('png', 'jpg')
|
||||||
|
- vquality: int, from 1 to 100
|
||||||
|
- vcursor: bool
|
||||||
|
- route: int, from 0 to 4
|
||||||
|
|
||||||
|
Route is currently write-only. This is a VMR bug.
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.vban.outstream[9].vformat = 'jpg'
|
||||||
|
$vmr.vban.outstream[9].vquality = 85
|
||||||
|
$vmr.vban.outstream[9].vcursor = $true
|
||||||
|
```
|
||||||
|
|
||||||
### Command
|
### Command
|
||||||
|
|
||||||
Certain 'special' commands are defined by the API as performing actions rather than setting values.
|
Certain 'special' commands are defined by the API as performing actions rather than setting values.
|
||||||
|
|
||||||
The following commands are available:
|
The following Command methods are available:
|
||||||
|
|
||||||
- show
|
- Show()
|
||||||
- hide
|
- Hide()
|
||||||
- restart
|
- Lock()
|
||||||
- shutdown
|
- Unlock()
|
||||||
- showvbanchat: boolean (write only)
|
- ShowVBANChat()
|
||||||
- lock: boolean (write only)
|
- HideVBANChat()
|
||||||
|
- Restart()
|
||||||
|
- Shutdown()
|
||||||
|
- Reset() : Reset all config
|
||||||
|
- Save($filepath) : string
|
||||||
|
- Load($filepath) : string
|
||||||
|
- StorePreset($index, $name) : (int, string)
|
||||||
|
- RecallPreset($index or $name) : (int or string)
|
||||||
|
- RunMacrobuttons() : Launches the macrobuttons app
|
||||||
|
- CloseMacrobuttons() : Closes the macrobuttons app
|
||||||
|
|
||||||
The following methods are available:
|
for example:
|
||||||
|
|
||||||
- Load($filepath): string
|
|
||||||
|
|
||||||
example:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.command.show
|
$vmr.command.Show()
|
||||||
|
$vmr.command.Lock()
|
||||||
$vmr.command.lock = $true
|
|
||||||
|
|
||||||
$vmr.command.Load("path/to/filename.xml")
|
$vmr.command.Load("path/to/filename.xml")
|
||||||
|
$vmr.command.RunMacrobuttons()
|
||||||
|
|
||||||
|
$vmr.command.StorePreset(63, 'example')
|
||||||
|
$vmr.command.StorePreset('example')
|
||||||
|
$vmr.command.StorePreset(63) # same as StorePreset(63, '')
|
||||||
|
$vmr.command.StorePreset() # same as StorePreset(''), overwrites last recalled
|
||||||
|
|
||||||
|
$vmr.command.RecallPreset('example')
|
||||||
|
$vmr.command.RecallPreset(63)
|
||||||
|
$vmr.command.RecallPreset() # same as RecallPreset(''), recalls last recalled
|
||||||
|
```
|
||||||
|
|
||||||
|
StorePreset('') and RecallPreset('') interact with the 'selected' preset. This is highlighted green in the GUI. Recalling a preset selects it. Storing a preset via GUI also selects it. Storing a preset with StorePreset does not select it.
|
||||||
|
|
||||||
|
### Fx
|
||||||
|
|
||||||
|
The following Fx properties are available:
|
||||||
|
|
||||||
|
- Reverb.on: bool
|
||||||
|
- Reverb.ab: bool
|
||||||
|
- Delay.on: bool
|
||||||
|
- Delay.ab: bool
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.fx.reverb.ab = $false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Patch
|
||||||
|
|
||||||
|
The following Patch properties are available:
|
||||||
|
|
||||||
|
- postFaderComposite: bool
|
||||||
|
- postFxInsert: bool
|
||||||
|
|
||||||
|
The following Patch members have methods Set($val) | Get() available:
|
||||||
|
|
||||||
|
- asio[i]: int, from 0 to ASIO input channels
|
||||||
|
- OutA2[i]-OutA5[i]: int, from 0 to ASIO output channels
|
||||||
|
- composite[i]: int, from 0 to strip channels
|
||||||
|
- insert[i]: bool
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.patch.asio[3].set(2) # patches ASIO input channel 2 (2) to strip 2, channel 2 (3)
|
||||||
|
$vmr.patch.OutA3[0].set(24) # patches bus A3, channel 1 (0) to ASIO output channel 24
|
||||||
|
$vmr.patch.composite[5].set(0) # sets composite channel 6 (5) to default bus channel
|
||||||
|
$vmr.patch.insert[4].get()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option
|
||||||
|
|
||||||
|
The following Option properties are available:
|
||||||
|
|
||||||
|
- sr: int, (32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||||
|
- asiosr: bool
|
||||||
|
- monitorOnSel: bool
|
||||||
|
- sliderMode: bool
|
||||||
|
- monitoringBus: int, from 0 to bus index
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.Option.sliderMode = $false # sets slider mode to absolute
|
||||||
|
```
|
||||||
|
|
||||||
|
#### buffers
|
||||||
|
|
||||||
|
The following Option.buffer properties are available:
|
||||||
|
|
||||||
|
- mme: int, (441, 480, 512, 576, 640, 704, 768, 896, 1024, 1536, 2048)
|
||||||
|
- wdm: int, (128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024, 1536, 2048)
|
||||||
|
- ks: int, (128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024, 1536, 2048)
|
||||||
|
- asio: int, (0, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024)
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.Option.buffer.wdm = 512
|
||||||
|
$vmr.Option.buffer.asio = 0 # to use default buffer size
|
||||||
|
```
|
||||||
|
|
||||||
|
#### delay[i]
|
||||||
|
|
||||||
|
The following Option.delay[i] methods are available:
|
||||||
|
|
||||||
|
- Set($val) : float, from 0.00 to 500.00
|
||||||
|
- Get()
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.Option.delay[2].set(30.26) # sets the delay for the third (2) bus
|
||||||
```
|
```
|
||||||
|
|
||||||
### Recorder
|
### Recorder
|
||||||
|
|
||||||
The following commands are available:
|
The following Recorder properties are available:
|
||||||
|
|
||||||
- play
|
- A1 - A5: bool
|
||||||
- stop
|
- B1 - B3: bool
|
||||||
- pause
|
- gain: float, from -60.00 to 12.00
|
||||||
- record
|
- armedbus: int, from 0 to bus index
|
||||||
- ff
|
- state: string, ('play', 'stop', 'record', 'pause')
|
||||||
- rew
|
- prerectime: int, from 0 to 20 seconds
|
||||||
- A1 - A5: boolean
|
- prefix: string, write-only
|
||||||
- B1 - B3: boolean
|
- filetype: string, write-only, ('wav', 'aiff', 'bwf', 'mp3')
|
||||||
- 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, (2, 4, 6, 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:
|
for example:
|
||||||
|
|
||||||
- Load($filepath): string
|
|
||||||
- GoTo($timestring): string, must match the format 'hh:mm:ss'
|
|
||||||
- FileType($format): string, ('wav', 'aiff', 'bwf', 'mp3')
|
|
||||||
|
|
||||||
example:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.recorder.play
|
|
||||||
$vmr.recorder.A1 = $true
|
$vmr.recorder.A1 = $true
|
||||||
|
$vmr.recorder.filetype = 'mp3'
|
||||||
|
$vmr.recorder.kbps = 256
|
||||||
|
```
|
||||||
|
|
||||||
|
The following Recorder methods are available:
|
||||||
|
|
||||||
|
- Play()
|
||||||
|
- Stop()
|
||||||
|
- Replay()
|
||||||
|
- FF()
|
||||||
|
- Rew()
|
||||||
|
- Record()
|
||||||
|
- Pause()
|
||||||
|
- Eject()
|
||||||
|
- Load($filepath) : string
|
||||||
|
- GoTo($timestring) : string, must match the format 'hh:mm:ss'
|
||||||
|
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.recorder.play()
|
||||||
$vmr.recorder.GoTo("00:01:15") # go to 1min 15sec into track
|
$vmr.recorder.GoTo("00:01:15") # go to 1min 15sec into track
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Mode
|
#### mode
|
||||||
|
|
||||||
The following commands are available:
|
The following Recorder.mode properties are available:
|
||||||
|
|
||||||
- recbus
|
- recbus: bool
|
||||||
- playonload
|
- playonload: bool
|
||||||
- loop
|
- loop: bool
|
||||||
- multitrack
|
- multitrack: bool
|
||||||
|
|
||||||
example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.recorder.mode.loop = $true
|
$vmr.recorder.mode.loop = $true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ArmStrip[i]|ArmBus[i]
|
#### armstrip[i]|armbus[i]
|
||||||
|
|
||||||
The following method is available:
|
The following Recorder.armstrip | Recorder.armbus methods are available:
|
||||||
|
|
||||||
- Set($val): boolean
|
- Set($val) : bool
|
||||||
|
- Get()
|
||||||
|
|
||||||
example:
|
for example:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$vmr.recorder.armstrip[0].Set($true)
|
$vmr.recorder.armstrip[0].Set($true)
|
||||||
@@ -542,19 +793,28 @@ 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:
|
Parameters:
|
||||||
|
|
||||||
- `kind`: Run tests of this kind
|
- `kind`: Run tests of this kind
|
||||||
- `tag`: Run tests tagged with this marker (currently `higher` or `lower`)
|
- `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:
|
*with Task*
|
||||||
|
|
||||||
`powershell .\tests\pre-commit.ps1 -k "potato" -t "higher" -log`
|
```console
|
||||||
|
task test -- -t "higher" -k "banana"
|
||||||
|
```
|
||||||
|
|
||||||
### Official Documentation
|
### 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/main/VoicemeeterRemoteAPI.pdf)
|
||||||
|
|||||||
11
Taskfile.yaml
Normal file
11
Taskfile.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
test:
|
||||||
|
desc: 'Run tests'
|
||||||
|
preconditions:
|
||||||
|
- sh: 'pwsh -c "if ([System.Version](Get-InstalledModule Pester).Version.ToString() -gt [System.Version]"5.7.0") { exit 0 } else { exit 1 }"'
|
||||||
|
msg: 'Pester version must be greater than 5.7.0'
|
||||||
|
cmds:
|
||||||
|
- echo "Running tests..."
|
||||||
|
- pwsh -c "tests\run.ps1 {{.CLI_ARGS}}"
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
|
[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,20 +20,20 @@ function get-value {
|
|||||||
|
|
||||||
function msgHandler {
|
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 '!') {
|
||||||
if ($output) { "Toggling " + $line.substring(1) | Write-Host }
|
'Toggling ' + $line.substring(1) | Write-Debug
|
||||||
$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('=')) {
|
||||||
if ($output) { "Setting $line" | Write-Host }
|
"Setting $line" | Write-Debug
|
||||||
$vmr.SendText($line)
|
$vmr.SendText($line)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($output) { "Getting $line" | Write-Host }
|
"Getting $line" | Write-Debug
|
||||||
$retval = get-value -vmr $vmr -line $line
|
$retval = get-value -vmr $vmr -line $line
|
||||||
$line + " = " + $retval | Write-Host
|
$line + ' = ' + $retval | Write-Host
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,10 +50,14 @@ function main {
|
|||||||
$vmr = Connect-Voicemeeter -Kind $kind
|
$vmr = Connect-Voicemeeter -Kind $kind
|
||||||
|
|
||||||
if ($interactive) {
|
if ($interactive) {
|
||||||
"Press <Enter> to exit" | Write-Host
|
'Press <Enter> to exit' | Write-Host
|
||||||
read-hostuntilempty -vmr $vmr
|
read-hostuntilempty -vmr $vmr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if ($script.Count -eq 0) {
|
||||||
|
'No script provided, exiting' | Write-Host
|
||||||
|
return
|
||||||
|
}
|
||||||
$script | ForEach-Object {
|
$script | ForEach-Object {
|
||||||
msgHandler -vmr $vmr -line $_
|
msgHandler -vmr $vmr -line $_
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ You may pass the following optional flags:
|
|||||||
|
|
||||||
for example:
|
for example:
|
||||||
|
|
||||||
`powershell.exe .\CLI.ps1 -o -k "banana" -s "strip[0].mute", "!strip[0].mute", "strip[0].mute", "bus[2].eq.on=1", "command.lock=1"`
|
```powershell
|
||||||
|
.\CLI.ps1 -o -k "banana" -s "strip[0].mute", "!strip[0].mute", "strip[0].mute", "bus[2].eq.on=1", "command.lock=1"
|
||||||
|
```
|
||||||
|
|
||||||
Expected output:
|
Expected output:
|
||||||
|
|
||||||
```
|
```powershell
|
||||||
Getting strip[0].mute
|
Getting strip[0].mute
|
||||||
strip[0].mute = 0
|
strip[0].mute = 0
|
||||||
Toggling strip[0].mute
|
Toggling strip[0].mute
|
||||||
|
|||||||
@@ -1,44 +1,69 @@
|
|||||||
<#
|
<#
|
||||||
1) Loop through an array of bus objects.
|
.SYNOPSIS
|
||||||
2) Mute first unmuted bus
|
Rotates through specified Voicemeeter buses, unmuting one at a time.
|
||||||
3) If next bus in array exists, unmute it, otherwise clear unmuted variable.
|
.DESCRIPTION
|
||||||
4) If every bus in array is muted, unmute the first bus specified in array.
|
This script connects to Voicemeeter Potato and allows the user to rotate through a set
|
||||||
|
of buses (1, 2, 4, and 6). When the user presses Enter, the next bus in the sequence is unmuted,
|
||||||
Credits go to @bobsupercow
|
while all other specified buses are muted. The user can exit the rotation by typing 'Q'.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
[cmdletbinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||||
|
|
||||||
$VerbosePreference = "Continue"
|
<#
|
||||||
|
A class that accepts a list of Voicemeeter buses and unmutes them one at a time in a round-robin fashion
|
||||||
|
#>
|
||||||
|
class BusRotator {
|
||||||
|
[object]$vmr = $null
|
||||||
|
[int]$CurrentIndex = -1
|
||||||
|
[object[]]$Buses
|
||||||
|
|
||||||
|
BusRotator([object]$vmr, [object[]]$buses) {
|
||||||
|
$this.vmr = $vmr
|
||||||
|
$this.Buses = $buses
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [object] GetNextBus() {
|
||||||
|
# Mute all buses in the list
|
||||||
|
foreach ($bus in $this.Buses) {
|
||||||
|
$bus.mute = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine the next bus to unmute
|
||||||
|
$this.CurrentIndex = ($this.CurrentIndex + 1) % $this.Buses.Count
|
||||||
|
|
||||||
|
return $this.Buses[$this.CurrentIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
[object] UnmuteNextBus() {
|
||||||
|
$nextBus = $this.GetNextBus()
|
||||||
|
$nextBus.mute = $false
|
||||||
|
return $nextBus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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])
|
# Mute all buses initially
|
||||||
$unmutedIndex = $null
|
foreach ($bus in $vmr.bus) {
|
||||||
|
$bus.mute = $true
|
||||||
# 1)
|
|
||||||
foreach ($bus in $buses) {
|
|
||||||
# 2)
|
|
||||||
if (-not $bus.mute) {
|
|
||||||
"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
|
|
||||||
$buses[$unmutedIndex].mute = $false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
else { Clear-Variable unmutedIndex }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# 4)
|
|
||||||
if ($null -eq $unmutedIndex) {
|
|
||||||
$buses[0].mute = $false
|
|
||||||
"unmuting bus $($buses[0].index)" | Write-Host
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$busesToRotate = @(
|
||||||
|
$vmr.bus[1],
|
||||||
|
$vmr.bus[2],
|
||||||
|
$vmr.bus[4],
|
||||||
|
$vmr.bus[6]
|
||||||
|
)
|
||||||
|
|
||||||
|
$rotator = [BusRotator]::new($vmr, $busesToRotate)
|
||||||
|
while ((Read-Host "Press Enter to rotate buses or type 'Q' to quit.") -ne 'Q') {
|
||||||
|
$nextBus = $rotator.UnmuteNextBus()
|
||||||
|
Write-Host "Bus $nextBus is now unmuted."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally { Disconnect-Voicemeeter }
|
finally { Disconnect-Voicemeeter }
|
||||||
|
|||||||
@@ -1,36 +1,33 @@
|
|||||||
|
[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
|
||||||
|
|
||||||
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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ExitStarted {
|
function ExitStarted {
|
||||||
param([System.Object]$data)
|
param([System.Object]$data)
|
||||||
"OBS shutdown has begun!" | Write-Host
|
'OBS shutdown has begun!' | Write-Host
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,12 +38,12 @@ function eventHandler($data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ConnFromFile {
|
function ConnFromFile {
|
||||||
$configpath = Join-Path $PSScriptRoot "config.psd1"
|
$configpath = Join-Path $PSScriptRoot 'config.psd1'
|
||||||
return Import-PowerShellDataFile -Path $configpath
|
return Import-PowerShellDataFile -Path $configpath
|
||||||
}
|
}
|
||||||
|
|
||||||
function main {
|
function main {
|
||||||
$vmr = Connect-Voicemeeter -Kind "basic"
|
$vmr = Connect-Voicemeeter -Kind 'basic'
|
||||||
|
|
||||||
$conn = ConnFromFile
|
$conn = ConnFromFile
|
||||||
$job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password
|
$job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password
|
||||||
|
|||||||
125
examples/streamdeck/README.md
Normal file
125
examples/streamdeck/README.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
Thanks to the guys at [Start Automating](https://startautomating.com/) it's possible to use this module straight from your Stream Deck.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### ScriptDeck
|
||||||
|
|
||||||
|
*Windows Powershell*
|
||||||
|
|
||||||
|
- [Windows ScriptDeck](https://marketplace.elgato.com/product/windows-scriptdeck-857f01dd-8fd4-44d5-8ec7-67ac850b21d3)
|
||||||
|
|
||||||
|
*Powershell core*
|
||||||
|
|
||||||
|
- [ScriptDeck](https://marketplace.elgato.com/product/scriptdeck-927e59aa-b42d-4da7-84cc-8c78f4dd7e18)
|
||||||
|
|
||||||
|
Note, even though one of them is named Windows they both work on Windows for different powershell versions, see [this issue](https://github.com/StartAutomating/ScriptDeck/issues/120)
|
||||||
|
|
||||||
|
### Voicemeeter API Powershell
|
||||||
|
|
||||||
|
- Install it as a module, see [Installation](https://github.com/onyx-and-iris/voicemeeter-api-powershell?tab=readme-ov-file#installation)
|
||||||
|
|
||||||
|
## How
|
||||||
|
|
||||||
|
Once ScriptDeck is installed create a button using *Powershell Script*, then:
|
||||||
|
|
||||||
|
### On one button
|
||||||
|
|
||||||
|
Due to the design of Voicemeeter's API you may only login/logout once per session so in order to program multiple buttons you must do the following for just ONE button (it can be any button).
|
||||||
|
|
||||||
|
#### Button 1
|
||||||
|
|
||||||
|
*When Loaded*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$global:vmr = Connect-Voicemeeter -Kind "banana"
|
||||||
|
```
|
||||||
|
|
||||||
|
*When Unloaded*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Disconnect-Voicemeeter
|
||||||
|
```
|
||||||
|
|
||||||
|
*When Pressed*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
if ($vmr.strip[0].mute) {
|
||||||
|
$vmr.bus[0].mute=1
|
||||||
|
$vmr.bus[1].mute=1
|
||||||
|
} else {
|
||||||
|
$vmr.bus[0].mute=0
|
||||||
|
$vmr.bus[1].mute=0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other buttons
|
||||||
|
|
||||||
|
Then your other buttons can have any scripts using the `$vmr` object:
|
||||||
|
|
||||||
|
#### Button 2
|
||||||
|
|
||||||
|
*When Pressed*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[1].mute=1
|
||||||
|
$vmr.strip[2].mute=1
|
||||||
|
|
||||||
|
if (-not $vmr.strip[0].mute) {
|
||||||
|
$vmr.strip[0].mute=1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Button 3
|
||||||
|
|
||||||
|
*When Pressed*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$vmr.strip[0].mute=$(-not $vmr.strip[0].mute)
|
||||||
|
$vmr.strip[1].mute=$(-not $vmr.strip[1].mute)
|
||||||
|
$vmr.strip[2].mute=$(-not $vmr.strip[2].mute)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Then let's say you have zillions of buttons you want to program, for each Stream Deck window configure ONE button as described above and the other buttons of the same window as described above.
|
||||||
|
|
||||||
|
If this explanation is unclear or you'd like me to add some screenshots just ask.
|
||||||
|
|
||||||
|
## Leveraging Powershell
|
||||||
|
|
||||||
|
Since we're now working with Powershell we can do some useful things, for example, lets create a button that interacts with Voicemeeter and OBS:
|
||||||
|
|
||||||
|
First make sure you've installed [obs-powershell](https://github.com/StartAutomating/obs-powershell).
|
||||||
|
|
||||||
|
Now let's create a button that only toggles some strip mutes if the current OBS scene is "LIVE".
|
||||||
|
|
||||||
|
#### Button
|
||||||
|
|
||||||
|
*When Loaded*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$global:vmr = Connect-Voicemeeter -Kind "banana"
|
||||||
|
|
||||||
|
Connect-OBS -WebSocketToken <websocket token>
|
||||||
|
```
|
||||||
|
|
||||||
|
*When Unloaded*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Disconnect-Voicemeeter
|
||||||
|
Disconnect-OBS
|
||||||
|
```
|
||||||
|
|
||||||
|
*When Pressed*
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$currentScene = $(Get-OBSCurrentProgramScene | Select-Object -ExpandProperty currentProgramSceneName)
|
||||||
|
|
||||||
|
if ($currentScene -eq "LIVE") {
|
||||||
|
$vmr.strip[0].mute=$(-not $vmr.strip[0].mute)
|
||||||
|
$vmr.strip[1].mute=$(-not $vmr.strip[1].mute)
|
||||||
|
$vmr.strip[2].mute=$(-not $vmr.strip[2].mute)
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -1,20 +1,34 @@
|
|||||||
. $PSScriptRoot\kinds.ps1
|
. $PSScriptRoot\errors.ps1
|
||||||
|
. $PSScriptRoot\meta.ps1
|
||||||
. $PSScriptRoot\base.ps1
|
. $PSScriptRoot\base.ps1
|
||||||
|
. $PSScriptRoot\kinds.ps1
|
||||||
|
. $PSScriptRoot\iremote.ps1
|
||||||
|
. $PSScriptRoot\arraymember.ps1
|
||||||
|
. $PSScriptRoot\io.ps1
|
||||||
|
. $PSScriptRoot\strip.ps1
|
||||||
|
. $PSScriptRoot\bus.ps1
|
||||||
|
. $PSScriptRoot\macrobuttons.ps1
|
||||||
|
. $PSScriptRoot\vban.ps1
|
||||||
|
. $PSScriptRoot\command.ps1
|
||||||
|
. $PSScriptRoot\recorder.ps1
|
||||||
|
. $PSScriptRoot\patch.ps1
|
||||||
|
. $PSScriptRoot\option.ps1
|
||||||
|
. $PSScriptRoot\fx.ps1
|
||||||
|
. $PSScriptRoot\profiles.ps1
|
||||||
|
|
||||||
class Remote {
|
class Remote {
|
||||||
|
[String]$vmpath
|
||||||
[Hashtable]$kind
|
[Hashtable]$kind
|
||||||
[Object]$profiles
|
[Object]$profiles
|
||||||
|
|
||||||
Remote ([String]$kindId) {
|
Remote ([String]$kindId) {
|
||||||
if (!(Setup_DLL)) {
|
$this.vmpath = 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] ToString() {
|
[string] ToString() {
|
||||||
return "Voicemeeter " + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1)
|
return 'Voicemeeter ' + $this.kind.name.substring(0, 1).toupper() + $this.kind.name.substring(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
[Remote] Login() {
|
[Remote] Login() {
|
||||||
@@ -31,7 +45,7 @@ class Remote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[String] GetVersion() {
|
[String] GetVersion() {
|
||||||
return Version
|
return VmVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
[void] Set_Profile([String]$config) {
|
[void] Set_Profile([String]$config) {
|
||||||
@@ -69,6 +83,8 @@ class RemoteBasic : Remote {
|
|||||||
[System.Collections.ArrayList]$button
|
[System.Collections.ArrayList]$button
|
||||||
[PSCustomObject]$vban
|
[PSCustomObject]$vban
|
||||||
[Object]$command
|
[Object]$command
|
||||||
|
[Object]$patch
|
||||||
|
[Object]$option
|
||||||
|
|
||||||
RemoteBasic () : base ('basic') {
|
RemoteBasic () : base ('basic') {
|
||||||
$this.strip = Make_Strips($this)
|
$this.strip = Make_Strips($this)
|
||||||
@@ -76,6 +92,8 @@ class RemoteBasic : Remote {
|
|||||||
$this.button = Make_Buttons
|
$this.button = Make_Buttons
|
||||||
$this.vban = Make_Vban($this)
|
$this.vban = Make_Vban($this)
|
||||||
$this.command = Make_Command($this)
|
$this.command = Make_Command($this)
|
||||||
|
$this.patch = Make_Patch($this)
|
||||||
|
$this.option = Make_Option($this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +103,8 @@ class RemoteBanana : Remote {
|
|||||||
[System.Collections.ArrayList]$button
|
[System.Collections.ArrayList]$button
|
||||||
[PSCustomObject]$vban
|
[PSCustomObject]$vban
|
||||||
[Object]$command
|
[Object]$command
|
||||||
|
[Object]$patch
|
||||||
|
[Object]$option
|
||||||
[Object]$recorder
|
[Object]$recorder
|
||||||
|
|
||||||
RemoteBanana () : base ('banana') {
|
RemoteBanana () : base ('banana') {
|
||||||
@@ -93,6 +113,8 @@ class RemoteBanana : Remote {
|
|||||||
$this.button = Make_Buttons
|
$this.button = Make_Buttons
|
||||||
$this.vban = Make_Vban($this)
|
$this.vban = Make_Vban($this)
|
||||||
$this.command = Make_Command($this)
|
$this.command = Make_Command($this)
|
||||||
|
$this.patch = Make_Patch($this)
|
||||||
|
$this.option = Make_Option($this)
|
||||||
$this.recorder = Make_Recorder($this)
|
$this.recorder = Make_Recorder($this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +125,9 @@ class RemotePotato : Remote {
|
|||||||
[System.Collections.ArrayList]$button
|
[System.Collections.ArrayList]$button
|
||||||
[PSCustomObject]$vban
|
[PSCustomObject]$vban
|
||||||
[Object]$command
|
[Object]$command
|
||||||
|
[Object]$fx
|
||||||
|
[Object]$patch
|
||||||
|
[Object]$option
|
||||||
[Object]$recorder
|
[Object]$recorder
|
||||||
|
|
||||||
RemotePotato () : base ('potato') {
|
RemotePotato () : base ('potato') {
|
||||||
@@ -111,6 +136,9 @@ class RemotePotato : Remote {
|
|||||||
$this.button = Make_Buttons
|
$this.button = Make_Buttons
|
||||||
$this.vban = Make_Vban($this)
|
$this.vban = Make_Vban($this)
|
||||||
$this.command = Make_Command($this)
|
$this.command = Make_Command($this)
|
||||||
|
$this.fx = Make_Fx($this)
|
||||||
|
$this.patch = Make_Patch($this)
|
||||||
|
$this.option = Make_Option($this)
|
||||||
$this.recorder = Make_Recorder($this)
|
$this.recorder = Make_Recorder($this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,23 +157,19 @@ 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
|
}
|
||||||
}
|
'banana' {
|
||||||
"banana" {
|
return Get-RemoteBanana
|
||||||
return Get-RemoteBanana
|
}
|
||||||
}
|
'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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
70
lib/arraymember.ps1
Normal file
70
lib/arraymember.ps1
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
class ArrayMember : IRemote {
|
||||||
|
[string]$prefix
|
||||||
|
[Object]$parent
|
||||||
|
|
||||||
|
ArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent
|
||||||
|
) : base ($index, $parent.remote) {
|
||||||
|
$this.prefix = $prefix
|
||||||
|
$this.parent = $parent
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
$parentId = $this.parent.identifier()
|
||||||
|
return "{0}.{1}[{2}]" -f $parentId, $this.prefix, $this.index
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] Set ($val) {
|
||||||
|
$this.Setter('', $val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoolArrayMember : ArrayMember {
|
||||||
|
BoolArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent
|
||||||
|
) : base ($index, $prefix, $parent) {}
|
||||||
|
|
||||||
|
[bool] Get () {
|
||||||
|
return $this.Getter('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntArrayMember : ArrayMember {
|
||||||
|
IntArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent
|
||||||
|
) : base ($index, $prefix, $parent) {}
|
||||||
|
|
||||||
|
[int] Get () {
|
||||||
|
return $this.Getter('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FloatArrayMember : ArrayMember {
|
||||||
|
[int]$decimals
|
||||||
|
|
||||||
|
FloatArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent, [int]$decimals
|
||||||
|
) : base ($index, $prefix, $parent) {
|
||||||
|
$this.decimals = $decimals
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent
|
||||||
|
) : base ($index, $prefix, $parent) {
|
||||||
|
$this.decimals = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
[double] Get () {
|
||||||
|
return [math]::Round($this.Getter(''), $this.decimals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringArrayMember : ArrayMember {
|
||||||
|
StringArrayMember (
|
||||||
|
[int]$index, [string]$prefix, [Object]$parent
|
||||||
|
) : base ($index, $prefix, $parent) {}
|
||||||
|
|
||||||
|
[string] Get () {
|
||||||
|
return $this.Getter_String('')
|
||||||
|
}
|
||||||
|
}
|
||||||
202
lib/base.ps1
202
lib/base.ps1
@@ -1,85 +1,108 @@
|
|||||||
. $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 })
|
|
||||||
}
|
|
||||||
|
|
||||||
$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) }
|
|
||||||
}
|
}
|
||||||
catch [LoginError] {
|
|
||||||
Write-Warning "$($_.Exception.ErrorMessage()). Fatal error, exiting..."
|
switch ($retval) {
|
||||||
exit -2
|
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.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$timeout = New-TimeSpan -Seconds 2
|
||||||
|
$sw = [diagnostics.stopwatch]::StartNew()
|
||||||
|
$exception = $null
|
||||||
|
do {
|
||||||
|
Start-Sleep -m 100
|
||||||
|
try {
|
||||||
|
'Successfully logged into Voicemeeter [' + $(VmType).ToUpper() + '] Version ' + $(VmVersion) | Write-Verbose
|
||||||
|
$exception = $null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
catch [CAPIError] {
|
||||||
|
$exception = $_
|
||||||
|
$exception | Write-Debug
|
||||||
|
}
|
||||||
|
} while ($sw.elapsed -lt $timeout)
|
||||||
|
|
||||||
|
if ($null -ne $exception) {
|
||||||
|
throw [VMRemoteError]::new('Timeout logging into the API.')
|
||||||
}
|
}
|
||||||
|
|
||||||
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
|
while (P_Dirty -or M_Dirty) { Start-Sleep -m 1 }
|
||||||
"VERSION:[" + $(VmType).ToUpper() + "]" | Write-Verbose
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Logout {
|
function Logout {
|
||||||
Start-Sleep -m 20
|
Start-Sleep -m 100
|
||||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Logout()
|
$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' = $(if ([Environment]::Is64BitOperatingSystem) { 4 } else { 1 })
|
||||||
|
'banana' = $(if ([Environment]::Is64BitOperatingSystem) { 5 } else { 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')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function P_Dirty {
|
function P_Dirty {
|
||||||
[bool][Voicemeeter.Remote]::VBVMR_IsParametersDirty()
|
$retval = [Voicemeeter.Remote]::VBVMR_IsParametersDirty()
|
||||||
|
if ($retval -notin @(0, 1)) {
|
||||||
|
throw [CAPIError]::new($retval, 'VBVMR_IsParametersDirty')
|
||||||
|
}
|
||||||
|
[bool]$retval
|
||||||
}
|
}
|
||||||
|
|
||||||
function M_Dirty {
|
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_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) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
if ($retval -notin @(0)) {
|
||||||
|
throw [CAPIError]::new($retval, 'VBVMR_GetVoicemeeterType')
|
||||||
|
}
|
||||||
switch ($ptr) {
|
switch ($ptr) {
|
||||||
1 { return "basic" }
|
1 { return 'basic' }
|
||||||
2 { return "banana" }
|
2 { return 'banana' }
|
||||||
3 { return "potato" }
|
3 { return 'potato' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Version {
|
function VmVersion {
|
||||||
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) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
if ($retval -notin @(0)) {
|
||||||
|
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
|
||||||
@@ -92,28 +115,22 @@ function Param_Get {
|
|||||||
param(
|
param(
|
||||||
[string]$PARAM, [bool]$IS_STRING = $false
|
[string]$PARAM, [bool]$IS_STRING = $false
|
||||||
)
|
)
|
||||||
Start-Sleep -m 50
|
Start-Sleep -m 30
|
||||||
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
|
||||||
}
|
}
|
||||||
@@ -123,17 +140,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 {
|
|
||||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
|
|
||||||
}
|
|
||||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
|
||||||
}
|
}
|
||||||
catch [CAPIError] {
|
else {
|
||||||
Write-Warning $_.Exception.ErrorMessage()
|
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameterFloat($PARAM, $VALUE)
|
||||||
|
if ($retval -notin @(0)) {
|
||||||
|
throw [CAPIError]::new($retval, 'VBVMR_SetParameterFloat')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,12 +158,9 @@ 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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,12 +172,9 @@ 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
|
||||||
}
|
}
|
||||||
@@ -173,8 +184,8 @@ function Param_Set_Multi {
|
|||||||
[hashtable]$HASH
|
[hashtable]$HASH
|
||||||
)
|
)
|
||||||
foreach ($key in $HASH.keys) {
|
foreach ($key in $HASH.keys) {
|
||||||
$classobj, $m2, $m3 = $key.Split("_")
|
$classobj, $m2, $m3 = $key.Split('_')
|
||||||
if ($m2 -match "^\d+$") { $index = [int]$m2 } else { $index = [int]$m3 }
|
if ($m2 -match '^\d+$') { $index = [int]$m2 } else { $index = [int]$m3 }
|
||||||
|
|
||||||
foreach ($h in $HASH[$key].GetEnumerator()) {
|
foreach ($h in $HASH[$key].GetEnumerator()) {
|
||||||
$property = $h.Name
|
$property = $h.Name
|
||||||
@@ -195,12 +206,12 @@ function Set_By_Script {
|
|||||||
param(
|
param(
|
||||||
[string]$script
|
[string]$script
|
||||||
)
|
)
|
||||||
try {
|
if ($script.Length -gt 48000) {
|
||||||
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
|
throw [VMRemoteError]::new('Script size cannot be larger than 48kB')
|
||||||
if ($retval) { throw [CAPIError]::new($retval, $MyInvocation.MyCommand) }
|
|
||||||
}
|
}
|
||||||
catch [CAPIError] {
|
$retval = [int][Voicemeeter.Remote]::VBVMR_SetParameters($script)
|
||||||
Write-Warning $_.Exception.ErrorMessage()
|
if ($retval -notin @(0)) {
|
||||||
|
throw [CAPIError]::new($retval, 'VBVMR_SetParameters')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,12 +220,9 @@ 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
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,11 @@
|
|||||||
function Setup_DLL {
|
. $PSScriptRoot\inst.ps1
|
||||||
try {
|
|
||||||
$vb_path = Get_VMPath
|
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($vb_path)) {
|
function Setup_DLL {
|
||||||
throw [VMRemoteError]::new("couldn't get Voicemeeter path")
|
$VMPATH = Get_VMPath
|
||||||
}
|
|
||||||
$dll = Join-Path -Path $vb_path -ChildPath ("VoicemeeterRemote" + `
|
$dll = Join-Path -Path $VMPATH -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")]
|
||||||
@@ -53,5 +46,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 $true
|
return $VMPATH
|
||||||
}
|
}
|
||||||
|
|||||||
173
lib/bus.ps1
173
lib/bus.ps1
@@ -1,60 +1,24 @@
|
|||||||
. $PSScriptRoot\meta.ps1
|
class Bus : IOControl {
|
||||||
|
|
||||||
class IBus {
|
|
||||||
[int]$index
|
|
||||||
[Object]$remote
|
|
||||||
|
|
||||||
IBus ([int]$index, [Object]$remote) {
|
|
||||||
$this.index = $index
|
|
||||||
$this.remote = $remote
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] identifier () {
|
|
||||||
return "Bus[" + $this.index + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] ToString() {
|
|
||||||
return $this.GetType().Name + $this.index
|
|
||||||
}
|
|
||||||
|
|
||||||
[single] Getter ($param) {
|
|
||||||
return $this.remote.Getter("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] Getter_String ($param) {
|
|
||||||
return $this.remote.Getter_String("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] Setter ($param, $val) {
|
|
||||||
$this.remote.Setter("$($this.identifier()).$param", $val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Bus : IBus {
|
|
||||||
[Object]$mode
|
[Object]$mode
|
||||||
[Object]$eq
|
[Object]$eq
|
||||||
[Object]$levels
|
[Object]$levels
|
||||||
|
|
||||||
Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddBoolMembers -PARAMS @('mono', 'mute')
|
AddBoolMembers -PARAMS @('sel', 'monitor')
|
||||||
AddStringMembers -PARAMS @('label')
|
AddIntMembers -PARAMS @('mono')
|
||||||
AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
|
AddFloatMembers -PARAMS @('returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
|
||||||
|
|
||||||
$this.mode = [BusMode]::new($index, $remote)
|
$this.mode = [BusMode]::new($index, $remote)
|
||||||
$this.eq = [BusEq]::new($index, $remote)
|
$this.eq = [BusEq]::new($index, $remote)
|
||||||
$this.levels = [BusLevels]::new($index, $remote)
|
$this.levels = [BusLevels]::new($index, $remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
[void] FadeTo ([single]$target, [int]$time) {
|
[string] identifier () {
|
||||||
$this.Setter('FadeTo', "($target, $time)")
|
return 'Bus[' + $this.index + ']'
|
||||||
}
|
|
||||||
|
|
||||||
[void] FadeBy ([single]$target, [int]$time) {
|
|
||||||
$this.Setter('FadeBy', "($target, $time)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BusLevels : IBus {
|
class BusLevels : IOLevels {
|
||||||
[int]$init
|
[int]$init
|
||||||
[int]$offset
|
[int]$offset
|
||||||
|
|
||||||
@@ -63,29 +27,12 @@ class BusLevels : IBus {
|
|||||||
$this.offset = 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() {
|
[System.Collections.ArrayList] All() {
|
||||||
return $this.Getter(3)
|
return $this.Getter(3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BusMode : IBus {
|
class BusMode : IRemote {
|
||||||
[System.Collections.ArrayList]$modes
|
[System.Collections.ArrayList]$modes
|
||||||
|
|
||||||
BusMode ([int]$index, [Object]$remote) : base ($index, $remote) {
|
BusMode ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
@@ -98,7 +45,7 @@ class BusMode : IBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Bus[" + $this.index + "].mode"
|
return 'Bus[' + $this.index + '].mode'
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] Get () {
|
[string] Get () {
|
||||||
@@ -109,15 +56,23 @@ class BusMode : IBus {
|
|||||||
}
|
}
|
||||||
return $mode
|
return $mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[void] Set ([string]$mode) {
|
||||||
|
if ($this.modes.Contains($mode)) {
|
||||||
|
$this.Setter($mode, $true)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw [System.ArgumentException]::new("Invalid mode: $mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BusEq : IBus {
|
class BusEq : IOEq {
|
||||||
BusEq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
BusEq ([int]$index, [Object]$remote) : base ($index, $remote, 'Bus') {
|
||||||
AddBoolMembers -PARAMS @('on', 'ab')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Bus[" + $this.index + "].EQ"
|
return 'Bus[' + $this.index + '].EQ'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,78 +81,30 @@ class PhysicalBus : Bus {
|
|||||||
|
|
||||||
PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
PhysicalBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
$this.device = [BusDevice]::new($index, $remote)
|
$this.device = [BusDevice]::new($index, $remote)
|
||||||
|
|
||||||
|
AddBoolMembers -PARAMS @('vaio')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BusDevice : IBus {
|
|
||||||
BusDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] identifier () {
|
|
||||||
return "Bus[" + $this.index + "].Device"
|
|
||||||
}
|
|
||||||
|
|
||||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('name')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).name is read only")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
|
||||||
{
|
|
||||||
$this.Getter('sr')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).sr is read only")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_wdm = $($this | Add-Member ScriptProperty 'wdm' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).wdm is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('wdm', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).ks is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('ks', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).mme is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('mme', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_asio = $($this | Add-Member ScriptProperty 'asio' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).asio is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('asio', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class VirtualBus : Bus {
|
class VirtualBus : Bus {
|
||||||
|
[Object]$device
|
||||||
|
|
||||||
VirtualBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
VirtualBus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
if ($this.remote.kind.name -eq 'basic') {
|
||||||
|
$this.device = [BusDevice]::new($index, $remote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BusDevice : IODevice {
|
||||||
|
BusDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
if ($this.index -eq 0) {
|
||||||
|
AddStringMembers -PARAMS @('asio') -WriteOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Bus[' + $this.index + '].Device'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
107
lib/command.ps1
107
lib/command.ps1
@@ -1,74 +1,73 @@
|
|||||||
. $PSScriptRoot\meta.ps1
|
class Special : IRemote {
|
||||||
. $PSScriptRoot\inst.ps1
|
Special ([Object]$remote) : base ($remote) {
|
||||||
|
AddActionMembers -PARAMS @('restart', 'shutdown', 'show', 'lock', 'reset')
|
||||||
class Special {
|
|
||||||
[Object]$remote
|
|
||||||
|
|
||||||
Special ([Object]$remote) {
|
|
||||||
AddActionMembers -PARAMS @('restart', 'shutdown', 'show')
|
|
||||||
|
|
||||||
$this.remote = $remote
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Command"
|
return 'Command'
|
||||||
}
|
|
||||||
|
|
||||||
[string] ToString() {
|
|
||||||
return $this.GetType().Name
|
|
||||||
}
|
|
||||||
|
|
||||||
[single] Getter ($param) {
|
|
||||||
return $this.remote.Getter("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] Setter ($param, $val) {
|
|
||||||
if ($val -is [Boolean]) {
|
|
||||||
$this.remote.Setter("$($this.identifier()).$param", $(if ($val) { 1 } else { 0 }))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this.remote.Setter("$($this.identifier()).$param", $val)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[void] RunMacrobuttons() {
|
[void] RunMacrobuttons() {
|
||||||
Start-Process -FilePath $(Join-Path -Path $(Get_VMPath) -ChildPath "VoicemeeterMacroButtons.exe")
|
'Launching the MacroButtons app' | Write-Verbose
|
||||||
|
Start-Process -FilePath $(Join-Path -Path $this.remote.vmpath -ChildPath 'VoicemeeterMacroButtons.exe')
|
||||||
}
|
}
|
||||||
|
|
||||||
[void] CloseMacrobuttons() {
|
[void] CloseMacrobuttons() {
|
||||||
Stop-Process -Name "VoicemeeterMacroButtons"
|
'Closing the MacroButtons app' | Write-Verbose
|
||||||
|
Stop-Process -Name 'VoicemeeterMacroButtons'
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_hide = $($this | Add-Member ScriptProperty 'hide' `
|
[void] Hide () {
|
||||||
{
|
$this.Setter('show', $false)
|
||||||
$this._hide = $this.Setter('show', $false)
|
}
|
||||||
} `
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_showvbanchat = $($this | Add-Member ScriptProperty 'showvbanchat' `
|
[void] Unlock () {
|
||||||
{
|
$this.Setter('lock', $false)
|
||||||
$this.Getter('DialogShow.VBANCHAT')
|
}
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([bool]$arg)
|
|
||||||
$this._showvbanchat = $this.Setter('DialogShow.VBANCHAT', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_lock = $($this | Add-Member ScriptProperty 'lock' `
|
[void] ShowVBANChat () {
|
||||||
{
|
$this.Setter('DialogShow.VBANCHAT', $true)
|
||||||
$this._lock = $this.Getter('lock')
|
}
|
||||||
} `
|
|
||||||
{
|
[void] HideVBANChat () {
|
||||||
param([bool]$arg)
|
$this.Setter('DialogShow.VBANCHAT', $false)
|
||||||
$this._lock = $this.Setter('lock', $arg)
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
[void] Load ([string]$filename) {
|
[void] Load ([string]$filename) {
|
||||||
$this.Setter('load', $filename)
|
$this.Setter('load', $filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[void] Save ([string]$filename) {
|
||||||
|
$this.Setter('save', $filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] StorePreset () {
|
||||||
|
$this.Setter('updatepreset', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] StorePreset ([string]$name) {
|
||||||
|
$this.Setter('updatepreset', $name)
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] StorePreset ([int]$index) {
|
||||||
|
$this.Setter('preset[{0}].store' -f $index, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] StorePreset ([int]$index, [string]$name) {
|
||||||
|
$this.Setter('preset[{0}].store' -f $index, $name)
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RecallPreset () {
|
||||||
|
$this.Setter('recallpreset', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RecallPreset ([string]$name) {
|
||||||
|
$this.Setter('recallpreset', $name)
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RecallPreset ([int]$index) {
|
||||||
|
$this.Setter('preset[{0}].recall' -f $index, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Make_Command([Object]$remote) {
|
function Make_Command([Object]$remote) {
|
||||||
|
|||||||
@@ -1,30 +1,19 @@
|
|||||||
class VMRemoteError : Exception {
|
class VMRemoteError : Exception {
|
||||||
[string]$msg
|
VMRemoteError ([string]$msg) : base ($msg) {
|
||||||
|
|
||||||
VMRemoteError ([string]$msg) {
|
|
||||||
$this.msg = $msg
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] ErrorMessage () {
|
|
||||||
return $this.msg
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginError : VMRemoteError {
|
class LoginError : VMRemoteError {
|
||||||
LoginError ([string]$msg) : base ([string]$msg) {
|
LoginError ([string]$msg) : base ($msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CAPIError : VMRemoteError {
|
class CAPIError : VMRemoteError {
|
||||||
[int]$retval
|
[int]$code
|
||||||
[string]$caller
|
[string]$function
|
||||||
|
|
||||||
CAPIError ([int]$retval, [string]$caller) {
|
CAPIError ([int]$code, [string]$function) : base ("$function returned $code") {
|
||||||
$this.retval = $retval
|
$this.code = $code
|
||||||
$this.caller = $caller
|
$this.function = $function
|
||||||
}
|
|
||||||
|
|
||||||
[string] ErrorMessage () {
|
|
||||||
return "CAPI return value: {0} in {1}" -f $this.retval, $this.caller
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
37
lib/fx.ps1
Normal file
37
lib/fx.ps1
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
class Fx : IRemote {
|
||||||
|
[Object]$reverb
|
||||||
|
[Object]$delay
|
||||||
|
|
||||||
|
Fx ([Object]$remote) : base ($remote) {
|
||||||
|
$this.reverb = [FxReverb]::new($remote)
|
||||||
|
$this.delay = [FxDelay]::new($remote)
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Fx'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FxReverb : IRemote {
|
||||||
|
FxReverb ([Object]$remote) : base ($remote) {
|
||||||
|
AddBoolMembers -PARAMS @('on', 'ab')
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Fx.Reverb'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FxDelay : IRemote {
|
||||||
|
FxDelay ([Object]$remote) : base ($remote) {
|
||||||
|
AddBoolMembers -PARAMS @('on', 'ab')
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Fx.Delay'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Make_Fx ([Object]$remote) {
|
||||||
|
return [Fx]::new($remote)
|
||||||
|
}
|
||||||
21
lib/inst.ps1
21
lib/inst.ps1
@@ -1,8 +1,19 @@
|
|||||||
function Get_VMPath {
|
function Get_VMPath {
|
||||||
$reg_path = "Registry::HKEY_LOCAL_MACHINE\Software" + `
|
$REG_KEY = @(
|
||||||
(& { if ([Environment]::Is64BitOperatingSystem) { "\WOW6432Node" } else { "" } }) + `
|
'Registry::HKEY_LOCAL_MACHINE',
|
||||||
"\Microsoft\Windows\CurrentVersion\Uninstall"
|
'Software',
|
||||||
$vm_key = "\VB:Voicemeeter {17359A74-1236-5467}\"
|
(& { if ([Environment]::Is64BitOperatingSystem) { 'WOW6432Node' } else { '' } }),
|
||||||
|
'Microsoft',
|
||||||
|
'Windows',
|
||||||
|
'CurrentVersion',
|
||||||
|
'Uninstall'
|
||||||
|
).Where({ $_ -ne '' }) -Join '\'
|
||||||
|
$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) -Join '\') -Name UninstallString | Split-Path -Parent)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw [VMRemoteError]::new('Unable to fetch Voicemeeter path from the Registry.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
108
lib/io.ps1
Normal file
108
lib/io.ps1
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
class IOControl : IRemote {
|
||||||
|
IOControl ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
AddBoolMembers -PARAMS @('mute')
|
||||||
|
AddFloatMembers -PARAMS @('gain')
|
||||||
|
AddStringMembers -PARAMS @('label')
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] FadeTo ([single]$target, [int]$time) {
|
||||||
|
$this.Setter('FadeTo', "($target, $time)")
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] FadeBy ([single]$target, [int]$time) {
|
||||||
|
$this.Setter('FadeBy', "($target, $time)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IOLevels : IRemote {
|
||||||
|
IOLevels ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [single] Convert([single]$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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IOEq : IRemote {
|
||||||
|
[System.Collections.ArrayList]$channel
|
||||||
|
[string]$kindOfEq
|
||||||
|
|
||||||
|
IOEq ([int]$index, [Object]$remote, [string]$kindOfEq) : base ($index, $remote) {
|
||||||
|
$this.kindOfEq = $kindOfEq
|
||||||
|
|
||||||
|
AddBoolMembers -PARAMS @('on', 'ab')
|
||||||
|
|
||||||
|
$this.channel = @()
|
||||||
|
for ($ch = 0; $ch -lt $remote.kind.eq_ch[$this.kindOfEq]; $ch++) {
|
||||||
|
$this.channel.Add([EqChannel]::new($ch, $this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] Load ([string]$filename) {
|
||||||
|
$param = 'Command.Load{0}Eq[{1}]' -f $this.kindOfEq, $this.index
|
||||||
|
$this.remote.Setter($param, $filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] Save ([string]$filename) {
|
||||||
|
$param = 'Command.Save{0}Eq[{1}]' -f $this.kindOfEq, $this.index
|
||||||
|
$this.remote.Setter($param, $filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EqChannel : IRemote {
|
||||||
|
[System.Collections.ArrayList]$cell
|
||||||
|
[Object]$eq
|
||||||
|
|
||||||
|
EqChannel ([int]$index, [Object]$eq) : base ($index, $eq.remote) {
|
||||||
|
$this.eq = $eq
|
||||||
|
|
||||||
|
if ($eq.kindOfEq -eq 'Bus') { AddFloatMembers -PARAMS @('trim', 'delay') }
|
||||||
|
|
||||||
|
$this.cell = @()
|
||||||
|
$cellCount = $this.remote.kind.cells
|
||||||
|
for ($c = 0; $c -lt $cellCount; $c++) {
|
||||||
|
$this.cell.Add([EqCell]::new($c, $this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return '{0}.Channel[{1}]' -f $this.eq.identifier(), $this.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EqCell : IRemote {
|
||||||
|
[Object]$channel
|
||||||
|
|
||||||
|
EqCell ([int]$index, [Object]$channel) : base ($index, $channel.remote) {
|
||||||
|
$this.channel = $channel
|
||||||
|
|
||||||
|
AddBoolMembers -PARAMS @('on')
|
||||||
|
AddIntMembers -PARAMS @('type')
|
||||||
|
AddFloatMembers -PARAMS @('f', 'gain', 'q')
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return '{0}.Cell[{1}]' -f $this.channel.identifier(), $this.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IODevice : IRemote {
|
||||||
|
IODevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
AddStringMembers -WriteOnly -PARAMS @('wdm', 'ks', 'mme')
|
||||||
|
AddStringMembers -ReadOnly -PARAMS @('name')
|
||||||
|
AddIntMembers -ReadOnly -PARAMS @('sr')
|
||||||
|
}
|
||||||
|
}
|
||||||
52
lib/iremote.ps1
Normal file
52
lib/iremote.ps1
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
class IRemote {
|
||||||
|
[Nullable[int]]$index
|
||||||
|
[Object]$remote
|
||||||
|
|
||||||
|
IRemote ([Object]$remote) {
|
||||||
|
$this.remote = $remote
|
||||||
|
}
|
||||||
|
|
||||||
|
IRemote ([int]$index, [Object]$remote) {
|
||||||
|
$this.index = $index
|
||||||
|
$this.remote = $remote
|
||||||
|
}
|
||||||
|
|
||||||
|
[single] Getter ($param) {
|
||||||
|
$this.ToString() + " Getter: $($this.Cmd($param))" | Write-Debug
|
||||||
|
return $this.remote.Getter($this.Cmd($param))
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] Getter_String ($param) {
|
||||||
|
$this.ToString() + " Getter_String: $($this.Cmd($param))" | Write-Debug
|
||||||
|
return $this.remote.Getter_String($this.Cmd($param))
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] Setter ($param, $val) {
|
||||||
|
$this.ToString() + " Setter: $($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"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Must be overridden by derived classes
|
||||||
|
[string] identifier () {
|
||||||
|
throw [System.NotImplementedException]::new("$($this.GetType().Name) must override identifier()")
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] ToString() {
|
||||||
|
if ($null -ne $this.index) {
|
||||||
|
return $this.GetType().Name + $this.index
|
||||||
|
}
|
||||||
|
return $this.GetType().Name
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,48 @@
|
|||||||
$KindMap = @{
|
$KindMap = @{
|
||||||
"basic" = @{
|
'basic' = @{
|
||||||
"name" = "basic"
|
'name' = 'basic'
|
||||||
"p_in" = 2
|
'p_in' = 2
|
||||||
"v_in" = 1
|
'v_in' = 1
|
||||||
"p_out" = 1
|
'p_out' = 1
|
||||||
"v_out" = 1
|
'v_out' = 1
|
||||||
"vban_in" = 4
|
'asio_in' = 4
|
||||||
"vban_out" = 4
|
'asio_out' = 8
|
||||||
|
'composite' = 0
|
||||||
|
'insert' = 0
|
||||||
|
'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||||
|
'eq_ch' = @{ 'strip' = 0; 'bus' = 0 }
|
||||||
|
'cells' = 0
|
||||||
|
'gainlayer' = 0
|
||||||
};
|
};
|
||||||
"banana" = @{
|
'banana' = @{
|
||||||
"name" = "banana"
|
'name' = 'banana'
|
||||||
"p_in" = 3
|
'p_in' = 3
|
||||||
"v_in" = 2
|
'v_in' = 2
|
||||||
"p_out" = 3
|
'p_out' = 3
|
||||||
"v_out" = 2
|
'v_out' = 2
|
||||||
"vban_in" = 8
|
'asio_in' = 6
|
||||||
"vban_out" = 8
|
'asio_out' = 8
|
||||||
|
'composite' = 8
|
||||||
|
'insert' = 22
|
||||||
|
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||||
|
'eq_ch' = @{ 'strip' = 0; 'bus' = 8 }
|
||||||
|
'cells' = 6
|
||||||
|
'gainlayer' = 0
|
||||||
};
|
};
|
||||||
"potato" = @{
|
'potato' = @{
|
||||||
"name" = "potato"
|
'name' = 'potato'
|
||||||
"p_in" = 5
|
'p_in' = 5
|
||||||
"v_in" = 3
|
'v_in' = 3
|
||||||
"p_out" = 5
|
'p_out' = 5
|
||||||
"v_out" = 3
|
'v_out' = 3
|
||||||
"vban_in" = 8
|
'asio_in' = 10
|
||||||
"vban_out" = 8
|
'asio_out' = 8
|
||||||
|
'composite' = 8
|
||||||
|
'insert' = 34
|
||||||
|
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||||
|
'eq_ch' = @{ 'strip' = 2; 'bus' = 8 }
|
||||||
|
'cells' = 6
|
||||||
|
'gainlayer' = 8
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
enum ButtonTypes {
|
||||||
|
State = 1
|
||||||
|
StateOnly = 2
|
||||||
|
Trigger = 3
|
||||||
|
}
|
||||||
|
|
||||||
class MacroButton {
|
class MacroButton {
|
||||||
[int32]$index
|
[int32]$index
|
||||||
|
|
||||||
@@ -10,40 +16,42 @@ 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 ($set, $mode) {
|
[void] Setter ($val, $mode) {
|
||||||
MB_Set -Id $this.index -SET $set -Mode $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' `
|
hidden $_state = $($this | Add-Member ScriptProperty 'state' `
|
||||||
{
|
{
|
||||||
[bool]$this.Getter(1)
|
[bool]$this.Getter([ButtonTypes]::State)
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param($arg)
|
param($arg)
|
||||||
$this._state = $this.Setter($arg, 1)
|
$this._state = $this.Setter($arg, [ButtonTypes]::State)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' `
|
hidden $_stateonly = $($this | Add-Member ScriptProperty 'stateonly' `
|
||||||
{
|
{
|
||||||
[bool]$this.Getter(2)
|
[bool]$this.Getter([ButtonTypes]::StateOnly)
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param($arg)
|
param($arg)
|
||||||
$this._stateonly = $this.Setter($arg, 2)
|
$this._stateonly = $this.Setter($arg, [ButtonTypes]::StateOnly)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' `
|
hidden $_trigger = $($this | Add-Member ScriptProperty 'trigger' `
|
||||||
{
|
{
|
||||||
[bool]$this.Getter(3)
|
[bool]$this.Getter([ButtonTypes]::Trigger)
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param($arg)
|
param($arg)
|
||||||
$this._trigger = $this.Setter($arg, 3)
|
$this._trigger = $this.Setter($arg, [ButtonTypes]::Trigger)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
98
lib/meta.ps1
98
lib/meta.ps1
@@ -1,64 +1,57 @@
|
|||||||
function AddBoolMembers () {
|
function AddBoolMembers () {
|
||||||
param(
|
param(
|
||||||
[String[]]$PARAMS
|
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||||
)
|
)
|
||||||
[hashtable]$Signatures = @{}
|
[hashtable]$Signatures = @{}
|
||||||
foreach ($param in $PARAMS) {
|
foreach ($param in $PARAMS) {
|
||||||
# Define getter
|
$Signatures['Getter'] = "[bool]`$this.Getter('{0}')" -f $param
|
||||||
$Signatures["Getter"] = "[bool]`$this.Getter('{0}')" -f $param
|
$Signatures['Setter'] = "param ( [bool]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||||
# Define setter
|
|
||||||
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
|
||||||
-f $param
|
-f $param
|
||||||
|
|
||||||
Addmember
|
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddFloatMembers () {
|
function AddFloatMembers () {
|
||||||
param(
|
param(
|
||||||
[String[]]$PARAMS
|
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly,
|
||||||
|
[int]$decimals = 2
|
||||||
)
|
)
|
||||||
[hashtable]$Signatures = @{}
|
[hashtable]$Signatures = @{}
|
||||||
foreach ($param in $PARAMS) {
|
foreach ($param in $PARAMS) {
|
||||||
# Define getter
|
$Signatures['Getter'] = "[math]::Round(`$this.Getter('{0}'), {1})" -f $param, $decimals
|
||||||
$Signatures["Getter"] = "[math]::Round(`$this.Getter('{0}'), 1)" -f $param
|
$Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||||
# Define setter
|
|
||||||
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
|
||||||
-f $param
|
-f $param
|
||||||
|
|
||||||
Addmember
|
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddIntMembers () {
|
function AddIntMembers () {
|
||||||
param(
|
param(
|
||||||
[String[]]$PARAMS
|
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||||
)
|
)
|
||||||
[hashtable]$Signatures = @{}
|
[hashtable]$Signatures = @{}
|
||||||
foreach ($param in $PARAMS) {
|
foreach ($param in $PARAMS) {
|
||||||
# Define getter
|
$Signatures['Getter'] = "[Int]`$this.Getter('{0}')" -f $param
|
||||||
$Signatures["Getter"] = "[Int]`$this.Getter('{0}')" -f $param
|
$Signatures['Setter'] = "param ( [Int]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||||
# Define setter
|
|
||||||
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
|
||||||
-f $param
|
-f $param
|
||||||
|
|
||||||
Addmember
|
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddStringMembers () {
|
function AddStringMembers () {
|
||||||
param(
|
param(
|
||||||
[String[]]$PARAMS
|
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||||
)
|
)
|
||||||
[hashtable]$Signatures = @{}
|
[hashtable]$Signatures = @{}
|
||||||
foreach ($param in $PARAMS) {
|
foreach ($param in $PARAMS) {
|
||||||
# Define getter
|
$Signatures['Getter'] = "[String]`$this.Getter_String('{0}')" -f $param
|
||||||
$Signatures["Getter"] = "[String]`$this.Getter_String('{0}')" -f $param
|
$Signatures['Setter'] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||||
# Define setter
|
|
||||||
$Signatures["Setter"] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
|
||||||
-f $param
|
-f $param
|
||||||
|
|
||||||
Addmember
|
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,14 +59,20 @@ function AddActionMembers () {
|
|||||||
param(
|
param(
|
||||||
[String[]]$PARAMS
|
[String[]]$PARAMS
|
||||||
)
|
)
|
||||||
[hashtable]$Signatures = @{}
|
|
||||||
foreach ($param in $PARAMS) {
|
foreach ($param in $PARAMS) {
|
||||||
# Define getter
|
$this | Add-Member -MemberType ScriptMethod -Name $param `
|
||||||
$Signatures["Getter"] = "`$this.Setter('{0}', `$true)" -f $param
|
-Value ([scriptblock]::Create("`$null = `$this.Setter('$param', 1)")) `
|
||||||
# Define setter
|
-Force
|
||||||
$Signatures["Setter"] = ""
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Addmember
|
function AddAliasMembers () {
|
||||||
|
param(
|
||||||
|
[hashtable]$MAP
|
||||||
|
)
|
||||||
|
foreach ($alias in $MAP.Keys) {
|
||||||
|
$this | Add-Member -MemberType AliasProperty -Name $alias `
|
||||||
|
-Value $MAP[$alias] -Force
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,33 +82,36 @@ function AddChannelMembers () {
|
|||||||
|
|
||||||
[System.Collections.ArrayList]$channels = @()
|
[System.Collections.ArrayList]$channels = @()
|
||||||
1..$($num_A + $num_B) | ForEach-Object {
|
1..$($num_A + $num_B) | ForEach-Object {
|
||||||
if ($_ -le $num_A) { $channels.Add("A{0}" -f $_) } else { $channels.Add("B{0}" -f $($_ - $num_A)) }
|
if ($_ -le $num_A) { $channels.Add('A{0}' -f $_) } else { $channels.Add('B{0}' -f $($_ - $num_A)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
AddBoolMembers -PARAMS $channels
|
AddBoolMembers -PARAMS $channels
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddGainlayerMembers () {
|
|
||||||
[hashtable]$Signatures = @{}
|
|
||||||
0..7 | ForEach-Object {
|
|
||||||
# Define getter
|
|
||||||
$Signatures["Getter"] = "`$this.Getter('gainlayer[{0}]')" -f $_
|
|
||||||
# Define setter
|
|
||||||
$Signatures["Setter"] = "param ( [Single]`$arg )`n`$this.Setter('gainlayer[{0}]', `$arg)" `
|
|
||||||
-f $_
|
|
||||||
$param = "gainlayer{0}" -f $_
|
|
||||||
$null = $param
|
|
||||||
|
|
||||||
Addmember
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Addmember {
|
function Addmember {
|
||||||
|
param(
|
||||||
|
[Switch]$readOnly, [Switch]$writeOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($readOnly -and $writeOnly) {
|
||||||
|
throw "AddMember: cannot be both readOnly and writeOnly for '$param'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Override signatures based on mode
|
||||||
|
if ($readOnly) {
|
||||||
|
$Signatures['Setter'] = "return Write-Warning (`"ERROR: `$(`$this.identifier()).{0} is read only`")" `
|
||||||
|
-f $param
|
||||||
|
}
|
||||||
|
elseif ($writeOnly) {
|
||||||
|
$Signatures['Getter'] = "return Write-Warning (`"ERROR: `$(`$this.identifier()).{0} is write only`")" `
|
||||||
|
-f $param
|
||||||
|
}
|
||||||
|
|
||||||
$AddMemberParams = @{
|
$AddMemberParams = @{
|
||||||
Name = $param
|
Name = $param
|
||||||
MemberType = 'ScriptProperty'
|
MemberType = 'ScriptProperty'
|
||||||
Value = [scriptblock]::Create($Signatures["Getter"])
|
Value = [scriptblock]::Create($Signatures['Getter'])
|
||||||
SecondValue = [scriptblock]::Create($Signatures["Setter"])
|
SecondValue = [scriptblock]::Create($Signatures['Setter'])
|
||||||
}
|
}
|
||||||
$this | Add-Member @AddMemberParams
|
$this | Add-Member @AddMemberParams
|
||||||
}
|
}
|
||||||
|
|||||||
138
lib/option.ps1
Normal file
138
lib/option.ps1
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
class Option : IRemote {
|
||||||
|
[System.Collections.ArrayList]$delay
|
||||||
|
[Object]$buffer
|
||||||
|
|
||||||
|
Option ([Object]$remote) : base ($remote) {
|
||||||
|
AddBoolMembers -PARAMS @('asiosr', 'monitorOnSel', 'sliderMode')
|
||||||
|
|
||||||
|
$this.buffer = [OptionBuffer]::new($remote)
|
||||||
|
|
||||||
|
$num_A = $this.remote.kind.p_out
|
||||||
|
if ($this.remote.kind.name -eq 'basic') {
|
||||||
|
$num_A += $this.remote.kind.v_out
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.delay = @()
|
||||||
|
for ($i = 0; $i -lt $num_A; $i++) {
|
||||||
|
$this.delay.Add([FloatArrayMember]::new($i, 'delay', $this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Option'
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
||||||
|
{
|
||||||
|
[int]$this.Getter('sr')
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$opts = @(32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
|
$this._sr = $this.Setter('sr', $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected one of', $opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
hidden $_monitoringBus = $($this | Add-Member ScriptProperty 'monitoringBus' `
|
||||||
|
{
|
||||||
|
foreach ($bus in 0..$($this.remote.kind.p_out + $this.remote.kind.v_out - 1)) {
|
||||||
|
if ($this.remote.Getter("Bus[$bus].Monitor")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $bus
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$busMax = $this.remote.kind.p_out + $this.remote.kind.v_out - 1
|
||||||
|
if ($arg -ge 0 -and $arg -le $busMax) {
|
||||||
|
$this._monitoringBus = $this.remote.Setter("Bus[$arg].Monitor", $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ("Expected a bus index between 0 and $busMax")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class OptionBuffer : IRemote {
|
||||||
|
OptionBuffer ([Object]$remote) : base ($remote) {}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Option.Buffer'
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
|
||||||
|
{
|
||||||
|
[int]$this.Getter('mme')
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$opts = @(441, 480, 512, 576, 640, 704, 768, 896, 1024, 1536, 2048)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
|
$this._mme = $this.Setter('mme', $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected one of', $opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
hidden $_wdm = $($this | Add-Member ScriptProperty 'wdm' `
|
||||||
|
{
|
||||||
|
[int]$this.Getter('wdm')
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$opts = @(128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024, 1536, 2048)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
|
$this._wdm = $this.Setter('wdm', $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected one of', $opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
|
||||||
|
{
|
||||||
|
[int]$this.Getter('ks')
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$opts = @(128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024, 1536, 2048)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
|
$this._ks = $this.Setter('ks', $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected one of', $opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
hidden $_asio = $($this | Add-Member ScriptProperty 'asio' `
|
||||||
|
{
|
||||||
|
[int]$this.Getter('asio')
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$opts = @(0, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 441, 448, 480, 512, 576, 640, 704, 768, 1024)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
|
$this._asio = $this.Setter('asio', $arg)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected one of', $opts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Make_Option ([Object]$remote) {
|
||||||
|
return [Option]::new($remote)
|
||||||
|
}
|
||||||
52
lib/patch.ps1
Normal file
52
lib/patch.ps1
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
class Patch : IRemote {
|
||||||
|
[System.Collections.ArrayList]$asio
|
||||||
|
[System.Collections.ArrayList]$composite
|
||||||
|
[System.Collections.ArrayList]$insert
|
||||||
|
|
||||||
|
Patch ([Object]$remote) : base ($remote) {
|
||||||
|
AddBoolMembers -PARAMS @('postFaderComposite', 'postFxInsert')
|
||||||
|
|
||||||
|
$this.AddASIOOutMembers()
|
||||||
|
|
||||||
|
$this.asio = @()
|
||||||
|
for ($i = 0; $i -lt $remote.kind.asio_in; $i++) {
|
||||||
|
$this.asio.Add([IntArrayMember]::new($i, 'asio', $this))
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.composite = @()
|
||||||
|
for ($i = 0; $i -lt $remote.kind.composite; $i++) {
|
||||||
|
$this.composite.Add([IntArrayMember]::new($i, 'composite', $this))
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.insert = @()
|
||||||
|
for ($i = 0; $i -lt $remote.kind.insert; $i++) {
|
||||||
|
$this.insert.Add([BoolArrayMember]::new($i, 'insert', $this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Patch'
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [void] AddASIOOutMembers () {
|
||||||
|
$num_A = $this.remote.kind.p_out
|
||||||
|
if ($this.remote.kind.name -eq 'basic') {
|
||||||
|
$num_A += $this.remote.kind.v_out
|
||||||
|
}
|
||||||
|
$asio_out = $this.remote.kind.asio_out
|
||||||
|
|
||||||
|
if ($asio_out -le 0) { return }
|
||||||
|
|
||||||
|
for ($a = 2; $a -le $num_A; $a++) {
|
||||||
|
[System.Collections.ArrayList]$members = @()
|
||||||
|
for ($i = 0; $i -lt $asio_out; $i++) {
|
||||||
|
$members.Add([IntArrayMember]::new($i, "OutA$a", $this))
|
||||||
|
}
|
||||||
|
Add-Member -InputObject $this -MemberType NoteProperty -Name "OutA$a" -Value $members -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Make_Patch ([Object]$remote) {
|
||||||
|
return [Patch]::new($remote)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
function Get_Profiles ([string]$kind_id) {
|
function Get_Profiles ([string]$kind_id) {
|
||||||
$basepath = Join-Path -Path $(Split-Path -Path $PSScriptRoot) -ChildPath "profiles"
|
$basepath = Join-Path -Path $(Split-Path -Path $PSScriptRoot) -ChildPath 'profiles'
|
||||||
if (Test-Path $basepath) {
|
if (Test-Path $basepath) {
|
||||||
$fullpath = Join-Path -Path $basepath -ChildPath $kind_id
|
$fullpath = Join-Path -Path $basepath -ChildPath $kind_id
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ function Get_Profiles ([string]$kind_id) {
|
|||||||
$filenames | ForEach-Object {
|
$filenames | ForEach-Object {
|
||||||
(Join-Path -Path $fullpath -ChildPath $_) | ForEach-Object {
|
(Join-Path -Path $fullpath -ChildPath $_) | ForEach-Object {
|
||||||
$filename = [System.IO.Path]::GetFileNameWithoutExtension($_)
|
$filename = [System.IO.Path]::GetFileNameWithoutExtension($_)
|
||||||
Write-Host ("Importing profile " + $kind_id + "/" + $filename)
|
Write-Host ('Importing profile ' + $kind_id + '/' + $filename)
|
||||||
$data[$filename] = Import-PowerShellDataFile -Path $_
|
$data[$filename] = Import-PowerShellDataFile -Path $_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,14 +24,9 @@ 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
|
|
||||||
Start-Sleep -m 1
|
|
||||||
}
|
|
||||||
catch [VMRemoteErrors] {
|
|
||||||
Write-Warning $_.Exception.ErrorMessage()
|
|
||||||
}
|
}
|
||||||
|
Param_Set_Multi -HASH $DATA.$CONF
|
||||||
|
Start-Sleep -m 1
|
||||||
}
|
}
|
||||||
|
|||||||
214
lib/recorder.ps1
214
lib/recorder.ps1
@@ -1,78 +1,62 @@
|
|||||||
. $PSScriptRoot\meta.ps1
|
class Recorder : IRemote {
|
||||||
|
|
||||||
class IRecorder {
|
|
||||||
[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
|
[Object]$mode
|
||||||
[System.Collections.ArrayList]$armstrip
|
[System.Collections.ArrayList]$armstrip
|
||||||
[System.Collections.ArrayList]$armbus
|
[System.Collections.ArrayList]$armbus
|
||||||
|
[System.Collections.ArrayList]$states
|
||||||
|
|
||||||
Recorder ([Object]$remote) : base ($remote) {
|
Recorder ([Object]$remote) : base ($remote) {
|
||||||
$this.mode = [RecorderMode]::new($remote)
|
$this.mode = [RecorderMode]::new($remote)
|
||||||
|
|
||||||
$this.armstrip = @()
|
$this.armstrip = @()
|
||||||
0..($remote.kind.p_in + $remote.kind.v_in - 1) | ForEach-Object {
|
$stripCount = $($remote.kind.p_in + $remote.kind.v_in)
|
||||||
$this.armstrip.Add([RecorderArmStrip]::new($_, $remote))
|
for ($i = 0; $i -lt $stripCount; $i++) {
|
||||||
}
|
$this.armstrip.Add([BoolArrayMember]::new($i, 'armstrip', $this))
|
||||||
$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')
|
$this.armbus = @()
|
||||||
|
$busCount = $($remote.kind.p_out + $remote.kind.v_out)
|
||||||
|
for ($i = 0; $i -lt $busCount; $i++) {
|
||||||
|
$this.armbus.Add([BoolArrayMember]::new($i, 'armbus', $this))
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.states = @('play', 'stop', 'record', 'pause')
|
||||||
|
AddActionMembers -PARAMS $this.states
|
||||||
|
|
||||||
|
AddActionMembers -PARAMS @('replay', 'ff', 'rew')
|
||||||
AddFloatMembers -PARAMS @('gain')
|
AddFloatMembers -PARAMS @('gain')
|
||||||
|
AddIntMembers -PARAMS @('prerectime')
|
||||||
|
AddStringMembers -PARAMS @('prefix') -WriteOnly
|
||||||
|
|
||||||
AddChannelMembers
|
AddChannelMembers
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Recorder"
|
return 'Recorder'
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] ToString() {
|
[void] Eject () {
|
||||||
return $this.GetType().Name
|
$this.remote.Setter('Command.Eject', 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_loop = $($this | Add-Member ScriptProperty 'loop' `
|
[void] Load ([string]$filename) {
|
||||||
{
|
$this.Setter('load', $filename)
|
||||||
[bool]$this.mode.loop
|
}
|
||||||
} `
|
|
||||||
{
|
[void] GoTo ([string]$timestring) {
|
||||||
param($arg)
|
try {
|
||||||
$this.mode.loop = $arg
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hidden $_samplerate = $($this | Add-Member ScriptProperty 'samplerate' `
|
hidden $_samplerate = $($this | Add-Member ScriptProperty 'samplerate' `
|
||||||
{
|
{
|
||||||
$this.Getter('samplerate')
|
[int]$this.Getter('samplerate')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
@@ -88,7 +72,7 @@ class Recorder : IRecorder {
|
|||||||
|
|
||||||
hidden $_bitresolution = $($this | Add-Member ScriptProperty 'bitresolution' `
|
hidden $_bitresolution = $($this | Add-Member ScriptProperty 'bitresolution' `
|
||||||
{
|
{
|
||||||
$this.Getter('bitresolution')
|
[int]$this.Getter('bitresolution')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
@@ -104,22 +88,23 @@ class Recorder : IRecorder {
|
|||||||
|
|
||||||
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
|
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
|
||||||
{
|
{
|
||||||
$this.Getter('channel')
|
[int]$this.Getter('channel')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
if ($arg -ge 1 -and $arg -le 8) {
|
$opts = @(2, 4, 6, 8)
|
||||||
|
if ($opts.Contains($arg)) {
|
||||||
$this._channel = $this.Setter('channel', $arg)
|
$this._channel = $this.Setter('channel', $arg)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
"channel got: $arg, expected value from 1 to 8" | Write-Warning
|
"channel got: $arg, expected one of $opts" | Write-Warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
hidden $_kbps = $($this | Add-Member ScriptProperty 'kbps' `
|
hidden $_kbps = $($this | Add-Member ScriptProperty 'kbps' `
|
||||||
{
|
{
|
||||||
$this.Getter('kbps')
|
[int]$this.Getter('kbps')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
@@ -133,72 +118,77 @@ class Recorder : IRecorder {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
[void] Load ([string]$filename) {
|
hidden $_filetype = $($this | Add-Member ScriptProperty 'filetype' `
|
||||||
$this.Setter('load', $filename)
|
{
|
||||||
}
|
return Write-Warning ("ERROR: $($this.identifier()).filetype is write only")
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([string]$arg)
|
||||||
|
[int]$val = 0
|
||||||
|
switch ($arg) {
|
||||||
|
'wav' { $val = 1 }
|
||||||
|
'aiff' { $val = 2 }
|
||||||
|
'bwf' { $val = 3 }
|
||||||
|
'mp3' { $val = 100 }
|
||||||
|
default { "Filetype() got: $arg, expected one of 'wav', 'aiff', 'bwf', 'mp3'" }
|
||||||
|
}
|
||||||
|
$this._filetype = $this.Setter('filetype', $val)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
[void] GoTo ([string]$timestring) {
|
hidden $_armedbus = $($this | Add-Member ScriptProperty 'armedbus' `
|
||||||
try {
|
{
|
||||||
if ([datetime]::ParseExact($timestring, "HH:mm:ss", $null)) {
|
foreach ($bus in 0..$($this.remote.kind.p_out + $this.remote.kind.v_out - 1)) {
|
||||||
$timespan = [timespan]::Parse($timestring)
|
if ($this.remote.Getter("Recorder.ArmBus[$bus]")) {
|
||||||
$this.Setter("GoTo", $timespan.TotalSeconds)
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $bus
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
$busMax = $this.remote.kind.p_out + $this.remote.kind.v_out - 1
|
||||||
|
if ($arg -ge 0 -and $arg -le $busMax) {
|
||||||
|
$this._armedbus = $this.remote.Setter("Recorder.ArmBus[$arg]", 1)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ("Expected a bus index between 0 and $busMax")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch [FormatException] {
|
)
|
||||||
"Time string $timestring does not match the required format 'hh:mm:ss'" | Write-Warning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] FileType($format) {
|
hidden $_state = $($this | Add-Member ScriptProperty 'state' `
|
||||||
[int]$val = 0
|
{
|
||||||
switch ($format) {
|
if ($this.Getter('pause')) { return 'pause' }
|
||||||
"wav" { $val = 1 }
|
foreach ($state in $this.states) {
|
||||||
"aiff" { $val = 2 }
|
if ($this.Getter($state)) {
|
||||||
"bwf" { $val = 3 }
|
break
|
||||||
"mp3" { $val = 100 }
|
}
|
||||||
default { "Filetype() got: $format, expected one of 'wav', 'aiff', 'bwf', 'mp3'" }
|
}
|
||||||
|
return $state
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([string]$arg)
|
||||||
|
if (-not $this.states.Contains($arg)) {
|
||||||
|
Write-Warning ("Recorder.State got: $arg, expected one of $($this.states)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ($arg -eq 'pause' -and -not $this.Getter('record')) {
|
||||||
|
Write-Warning ("Recorder.State can only be set to 'pause' when recording")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$this._state = $this.Setter($arg, 1)
|
||||||
}
|
}
|
||||||
$this.Setter("filetype", $val)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RecorderMode : IRecorder {
|
class RecorderMode : IRemote {
|
||||||
RecorderMode ([Object]$remote) : base ($remote) {
|
RecorderMode ([Object]$remote) : base ($remote) {
|
||||||
AddBoolMembers -PARAMS @('recbus', 'playonload', 'loop', 'multitrack')
|
AddBoolMembers -PARAMS @('recbus', 'playonload', 'loop', 'multitrack')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Recorder.Mode"
|
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)]"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
252
lib/strip.ps1
252
lib/strip.ps1
@@ -1,60 +1,27 @@
|
|||||||
. $PSScriptRoot\meta.ps1
|
class Strip : IOControl {
|
||||||
|
[System.Collections.ArrayList]$gainlayer
|
||||||
class IStrip {
|
|
||||||
[int]$index
|
|
||||||
[Object]$remote
|
|
||||||
|
|
||||||
IStrip ([int]$index, [Object]$remote) {
|
|
||||||
$this.index = $index
|
|
||||||
$this.remote = $remote
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] identifier () {
|
|
||||||
return "Strip[" + $this.index + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
[single] Getter ($param) {
|
|
||||||
return $this.remote.Getter("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] Getter_String ($param) {
|
|
||||||
return $this.remote.Getter_String("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] Setter ($param, $val) {
|
|
||||||
$this.remote.Setter("$($this.identifier()).$param", $val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Strip : IStrip {
|
|
||||||
[Object]$levels
|
[Object]$levels
|
||||||
|
|
||||||
Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddBoolMembers -PARAMS @('mono', 'solo', 'mute')
|
AddBoolMembers -PARAMS @('solo')
|
||||||
AddIntMembers -PARAMS @('limit')
|
AddFloatMembers -PARAMS @('limit', 'pan_x', 'pan_y')
|
||||||
AddFloatMembers -PARAMS @('gain', 'pan_x', 'pan_y')
|
|
||||||
AddStringMembers -PARAMS @('label')
|
|
||||||
|
|
||||||
AddChannelMembers
|
AddChannelMembers
|
||||||
AddGainlayerMembers
|
|
||||||
|
|
||||||
$this.levels = [StripLevels]::new($index, $remote)
|
$this.levels = [StripLevels]::new($index, $remote)
|
||||||
|
|
||||||
|
$this.gainlayer = @()
|
||||||
|
for ($i = 0; $i -lt $remote.kind.gainlayer; $i++) {
|
||||||
|
$this.gainlayer.Add([FloatArrayMember]::new($i, 'gainlayer', $this))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] ToString() {
|
[string] identifier () {
|
||||||
return $this.GetType().Name + $this.index
|
return 'Strip[' + $this.index + ']'
|
||||||
}
|
|
||||||
|
|
||||||
[void] FadeTo ([single]$target, [int]$time) {
|
|
||||||
$this.Setter('FadeTo', "($target, $time)")
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] FadeBy ([single]$target, [int]$time) {
|
|
||||||
$this.Setter('FadeBy', "($target, $time)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripLevels : IStrip {
|
class StripLevels : IOLevels {
|
||||||
[int]$init
|
[int]$init
|
||||||
[int]$offset
|
[int]$offset
|
||||||
|
|
||||||
@@ -70,23 +37,6 @@ class StripLevels : IStrip {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[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() {
|
[System.Collections.ArrayList] PreFader() {
|
||||||
return $this.Getter(0)
|
return $this.Getter(0)
|
||||||
}
|
}
|
||||||
@@ -106,169 +56,145 @@ class PhysicalStrip : Strip {
|
|||||||
[Object]$denoiser
|
[Object]$denoiser
|
||||||
[Object]$eq
|
[Object]$eq
|
||||||
[Object]$device
|
[Object]$device
|
||||||
|
[Object]$audibility
|
||||||
|
[Object]$pitch
|
||||||
|
|
||||||
PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddFloatMembers -PARAMS @('color_x', 'color_y', 'fx_x', 'fx_y')
|
AddFloatMembers -PARAMS @('color_x', 'color_y', 'fx_x', 'fx_y')
|
||||||
AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2')
|
AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2')
|
||||||
AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2')
|
AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2')
|
||||||
|
AddBoolMembers -PARAMS @('mono', 'vaio')
|
||||||
|
|
||||||
$this.comp = [StripComp]::new($index, $remote)
|
$this.comp = [StripComp]::new($index, $remote)
|
||||||
$this.gate = [StripGate]::new($index, $remote)
|
$this.gate = [StripGate]::new($index, $remote)
|
||||||
$this.denoiser = [StripDenoiser]::new($index, $remote)
|
$this.denoiser = [StripDenoiser]::new($index, $remote)
|
||||||
|
$this.pitch = [StripPitch]::new($index, $remote)
|
||||||
|
$this.audibility = [StripAudibility]::new($index, $remote)
|
||||||
$this.eq = [StripEq]::new($index, $remote)
|
$this.eq = [StripEq]::new($index, $remote)
|
||||||
$this.device = [StripDevice]::new($index, $remote)
|
$this.device = [StripDevice]::new($index, $remote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripComp : IStrip {
|
class StripKnob : IRemote {
|
||||||
|
StripKnob ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
||||||
|
{
|
||||||
|
[math]::Round($this.Getter(''), 2)
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([single]$arg)
|
||||||
|
return $this.Setter('', $arg)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class StripComp : StripKnob {
|
||||||
StripComp ([int]$index, [Object]$remote) : base ($index, $remote) {
|
StripComp ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
|
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
|
||||||
AddBoolMembers -PARAMS @('makeup')
|
AddBoolMembers -PARAMS @('makeup')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Strip[" + $this.index + "].Comp"
|
return 'Strip[' + $this.index + '].Comp'
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripGate : IStrip {
|
class StripGate : StripKnob {
|
||||||
StripGate ([int]$index, [Object]$remote) : base ($index, $remote) {
|
StripGate ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
|
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Strip[" + $this.index + "].Gate"
|
return 'Strip[' + $this.index + '].Gate'
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripDenoiser : IStrip {
|
class StripDenoiser : StripKnob {
|
||||||
StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
|
StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
AddFloatMembers -PARAMS @('threshold')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Strip[" + $this.index + "].Denoiser"
|
return 'Strip[' + $this.index + '].Denoiser'
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripEq : IStrip {
|
class StripPitch : IRemote {
|
||||||
StripEq ([int]$index, [Object]$remote) : base ($index, $remote) {
|
StripPitch ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddBoolMembers -PARAMS @('on', 'ab')
|
AddBoolMembers -PARAMS @('on')
|
||||||
|
AddFloatMembers -PARAMS @('drywet', 'pitchvalue', 'loformant', 'medformant', 'hiformant')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Strip[" + $this.index + "].EQ"
|
return 'Strip[' + $this.index + '].Pitch'
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RecallPreset ([int]$presetIndex) {
|
||||||
|
$this.Setter('RecallPreset', $presetIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StripDevice : IStrip {
|
class StripAudibility : StripKnob {
|
||||||
|
StripAudibility ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Strip[' + $this.index + '].Audibility'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StripEq : IOEq {
|
||||||
|
StripEq ([int]$index, [Object]$remote) : base ($index, $remote, 'Strip') {
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] identifier () {
|
||||||
|
return 'Strip[' + $this.index + '].EQ'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StripDevice : IODevice {
|
||||||
StripDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
StripDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
return "Strip[" + $this.index + "].Device"
|
return 'Strip[' + $this.index + '].Device'
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('name')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).name is read only")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
|
||||||
{
|
|
||||||
$this.Getter('sr')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).sr is read only")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_wdm = $($this | Add-Member ScriptProperty 'wdm' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).wdm is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('wdm', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).ks is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('ks', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).mme is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('mme', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_asio = $($this | Add-Member ScriptProperty 'asio' `
|
|
||||||
{
|
|
||||||
return Write-Warning ("ERROR: $($this.identifier()).asio is write only")
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param($arg)
|
|
||||||
return $this.Setter('asio', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class VirtualStrip : Strip {
|
class VirtualStrip : Strip {
|
||||||
VirtualStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
VirtualStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||||
AddBoolMembers -PARAMS @('mc')
|
AddBoolMembers -PARAMS @('mc')
|
||||||
AddIntMembers -PARAMS @('k')
|
AddIntMembers -PARAMS @('k')
|
||||||
|
AddFloatMembers -PARAMS @('eqgain1', 'eqgain2', 'eqgain3')
|
||||||
|
|
||||||
|
AddAliasMembers -MAP @{
|
||||||
|
mono = 'mc'
|
||||||
|
karaoke = 'k'
|
||||||
|
bass = 'eqgain1'
|
||||||
|
low = 'eqgain1'
|
||||||
|
mid = 'eqgain2'
|
||||||
|
med = 'eqgain2'
|
||||||
|
treble = 'eqgain3'
|
||||||
|
high = 'eqgain3'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[void] AppGain ([string]$appname, [single]$gain) {
|
[void] AppGain ([string]$appname, [single]$gain) {
|
||||||
$this.Setter('AppGain', "(`"$appname`", $gain)")
|
$this.Setter('AppGain', "(`"$appname`", $gain)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[void] AppGain ([int]$appindex, [single]$gain) {
|
||||||
|
$this.Setter("App[$appindex].Gain", $gain)
|
||||||
|
}
|
||||||
|
|
||||||
[void] AppMute ([string]$appname, [bool]$mutestate) {
|
[void] AppMute ([string]$appname, [bool]$mutestate) {
|
||||||
$this.Setter('AppMute', "(`"$appname`", $(if ($mutestate) { 1 } else { 0 })")
|
$this.Setter('AppMute', "(`"$appname`", $(if ($mutestate) { 1 } else { 0 }))")
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] AppMute ([int]$appindex, [bool]$mutestate) {
|
||||||
|
$this.Setter("App[$appindex].Mute", $mutestate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
298
lib/vban.ps1
298
lib/vban.ps1
@@ -1,75 +1,23 @@
|
|||||||
class IVban {
|
class Vban : IRemote {
|
||||||
[int32]$index
|
|
||||||
[Object]$remote
|
|
||||||
[string]$direction
|
[string]$direction
|
||||||
|
|
||||||
IVban ([int]$index, [Object]$remote, [string]$direction) {
|
Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote) {
|
||||||
$this.index = $index
|
|
||||||
$this.remote = $remote
|
|
||||||
$this.direction = $direction
|
$this.direction = $direction
|
||||||
|
|
||||||
|
AddBoolMembers -PARAMS @('on')
|
||||||
|
AddStringMembers -PARAMS @('name', 'ip')
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] identifier () {
|
[string] identifier () {
|
||||||
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) {
|
|
||||||
return $this.remote.Getter("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[string] Getter_String ($param) {
|
|
||||||
return $this.remote.Getter_String("$($this.identifier()).$param")
|
|
||||||
}
|
|
||||||
|
|
||||||
[void] Setter ($param, $val) {
|
|
||||||
$this.remote.Setter("$($this.identifier()).$param", $val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Vban : IVban {
|
|
||||||
Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
|
||||||
}
|
|
||||||
|
|
||||||
hidden $_on = $($this | Add-Member ScriptProperty 'on' `
|
|
||||||
{
|
|
||||||
$this.Getter('on')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([bool]$arg)
|
|
||||||
$this._on = $this.Setter('on', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('name')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([string]$arg)
|
|
||||||
$this._name = $this.Setter('name', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_ip = $($this | Add-Member ScriptProperty 'ip' `
|
|
||||||
{
|
|
||||||
$this.Getter_String('ip')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([string]$arg)
|
|
||||||
$this._ip = $this.Setter('ip', $arg)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_port = $($this | Add-Member ScriptProperty 'port' `
|
hidden $_port = $($this | Add-Member ScriptProperty 'port' `
|
||||||
{
|
{
|
||||||
$this.Getter('port')
|
[int]$this.Getter('port')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([string]$arg)
|
param([int]$arg)
|
||||||
if ($arg -ge 1024 -and $arg -le 65535) {
|
if ($arg -ge 1024 -and $arg -le 65535) {
|
||||||
$this._port = $this.Setter('port', $arg)
|
$this._port = $this.Setter('port', $arg)
|
||||||
}
|
}
|
||||||
@@ -78,40 +26,72 @@ class Vban : IVban {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanAudio : Vban {
|
||||||
|
VbanAudio ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||||
|
AddIntMembers -PARAMS @('quality', 'route')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanMidi : Vban {
|
||||||
|
VbanMidi ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanText : Vban {
|
||||||
|
VbanText ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanVideo : Vban {
|
||||||
|
VbanVideo ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanInAudio : VbanAudio {
|
||||||
|
VbanInAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'in') {
|
||||||
|
AddIntMembers -ReadOnly -PARAMS @('sr', 'channel')
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden $_bit = $($this | Add-Member ScriptProperty 'bit' `
|
||||||
|
{
|
||||||
|
$val = if ($this.Getter('bit') -eq 1) { 16 } else { 24 }
|
||||||
|
return $val
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
Write-Warning ("ERROR: $($this.identifier()).bit is read only")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanInMidi : VbanMidi {
|
||||||
|
VbanInMidi ([int]$index, [Object]$remote) : base ($index, $remote, 'in') {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanInText : VbanText {
|
||||||
|
VbanInText ([int]$index, [Object]$remote) : base ($index, $remote, 'in') {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VbanOutAudio : VbanAudio {
|
||||||
|
VbanOutAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||||
|
AddIntMembers -PARAMS @('channel')
|
||||||
|
}
|
||||||
|
|
||||||
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
||||||
{
|
{
|
||||||
$this.Getter('sr')
|
[int]$this.Getter('sr')
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||||
else {
|
if ($opts.Contains($arg)) {
|
||||||
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
$this._sr = $this.Setter('sr', $arg)
|
||||||
if ($opts.Contains($arg)) {
|
|
||||||
$this._port = $this.Setter('sr', $arg)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Warning ('Expected one of', $opts)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
|
|
||||||
{
|
|
||||||
$this.Getter('channel')
|
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([int]$arg)
|
|
||||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
|
||||||
else {
|
else {
|
||||||
if ($arg -ge 1 -and $arg -le 8) {
|
Write-Warning ('Expected one of', $opts)
|
||||||
$this._channel = $this.Setter('channel', $arg)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Warning ('Expected value from 1 to 8')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -123,78 +103,108 @@ class Vban : IVban {
|
|||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([int]$arg)
|
||||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
if (@(16, 24).Contains($arg)) {
|
||||||
|
$val = if ($arg -eq 16) { 1 } else { 2 }
|
||||||
|
$this._bit = $this.Setter('bit', $val)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (@(16, 24).Contains($arg)) {
|
Write-Warning ('Expected value 16 or 24')
|
||||||
$val = if ($arg -eq 16) { 1 } else { 2 }
|
|
||||||
$this._bit = $this.Setter('bit', $val)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Warning ('Expected value 16 or 24')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
hidden $_quality = $($this | Add-Member ScriptProperty 'quality' `
|
class VbanOutMidi : VbanMidi {
|
||||||
{
|
VbanOutMidi ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||||
$this.Getter('quality')
|
}
|
||||||
} `
|
|
||||||
{
|
|
||||||
param([int]$arg)
|
|
||||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
|
||||||
else {
|
|
||||||
if ($arg -ge 0 -and $arg -le 4) {
|
|
||||||
$this._quality = $this.Setter('quality', $arg)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Warning ('Expected value from 0 to 4')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
hidden $_route = $($this | Add-Member ScriptProperty 'route' `
|
hidden $_route = $($this | Add-Member ScriptProperty 'route' `
|
||||||
{
|
{
|
||||||
$this.Getter('route')
|
[string]$val = ''
|
||||||
|
switch ($this.Getter('route')) {
|
||||||
|
0 { $val = 'none' }
|
||||||
|
1 { $val = 'midi_in' }
|
||||||
|
2 { $val = 'aux_in' }
|
||||||
|
4 { $val = 'vban_in' }
|
||||||
|
7 { $val = 'all_in' }
|
||||||
|
8 { $val = 'midi_out' }
|
||||||
|
}
|
||||||
|
return $val
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([int]$arg)
|
param([string]$arg)
|
||||||
if ($this.direction -eq "in") { Write-Warning ('Error, read only value') }
|
[int]$val = 0
|
||||||
else {
|
switch ($arg) {
|
||||||
if ($arg -ge 0 -and $arg -le 8) {
|
'none' { $val = 0 }
|
||||||
$this._route = $this.Setter('route', $arg)
|
'midi_in' { $val = 1 }
|
||||||
}
|
'aux_in' { $val = 2 }
|
||||||
else {
|
'vban_in' { $val = 4 }
|
||||||
Write-Warning ('Expected value from 0 to 8')
|
'all_in' { $val = 7 }
|
||||||
}
|
'midi_out' { $val = 8 }
|
||||||
|
default { Write-Warning ("route got: $arg, expected one of 'none', 'midi_in', 'aux_in', 'vban_in', 'all_in', 'midi_out'") }
|
||||||
}
|
}
|
||||||
|
$this._route = $this.Setter('route', $val)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class VbanOutVideo : VbanVideo {
|
||||||
class VbanInstream : Vban {
|
VbanOutVideo ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||||
VbanInstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
AddIntMembers -PARAMS @('vfps', 'vquality')
|
||||||
|
AddIntMembers -WriteOnly -PARAMS @('route')
|
||||||
|
AddBoolMembers -PARAMS @('vcursor')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hidden $_vformat = $($this | Add-Member ScriptProperty 'vformat' `
|
||||||
|
{
|
||||||
|
[string]$val = ''
|
||||||
|
switch ($this.Getter('vformat')) {
|
||||||
|
1 { $val = 'png' }
|
||||||
|
2 { $val = 'jpg' }
|
||||||
|
}
|
||||||
|
return $val
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([string]$arg)
|
||||||
|
[int]$val = 0
|
||||||
|
switch ($arg) {
|
||||||
|
'png' { $val = 1 }
|
||||||
|
'jpg' { $val = 2 }
|
||||||
|
default { Write-Warning ("vformat got: $arg, expected one of 'png', 'jpg'") }
|
||||||
|
}
|
||||||
|
$this._vformat = $this.Setter('vformat', $val)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VbanOutstream : Vban {
|
|
||||||
VbanOutstream ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Make_Vban ([Object]$remote) {
|
function Make_Vban ([Object]$remote) {
|
||||||
[System.Collections.ArrayList]$instream = @()
|
[System.Collections.ArrayList]$instream = @()
|
||||||
[System.Collections.ArrayList]$outstream = @()
|
[System.Collections.ArrayList]$outstream = @()
|
||||||
|
|
||||||
0..$($remote.kind.vban_in - 1) | ForEach-Object {
|
$totalInstreams = $remote.kind.vban.in + $remote.kind.vban.midi + $remote.kind.vban.text
|
||||||
[void]$instream.Add([VbanInstream]::new($_, $remote, "in"))
|
$totalOutstreams = $remote.kind.vban.out + $remote.kind.vban.midi + $remote.kind.vban.video
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $totalInstreams; $i++) {
|
||||||
|
if ($i -lt $remote.kind.vban.in) {
|
||||||
|
[void]$instream.Add([VbanInAudio]::new($i, $remote))
|
||||||
|
}
|
||||||
|
elseif ($i -lt ($remote.kind.vban.in + $remote.kind.vban.midi)) {
|
||||||
|
[void]$instream.Add([VbanInMidi]::new($i, $remote))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[void]$instream.Add([VbanInText]::new($i, $remote))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0..$($remote.kind.vban_out - 1) | ForEach-Object {
|
for ($i = 0; $i -lt $totalOutstreams; $i++) {
|
||||||
[void]$outstream.Add([VbanOutstream]::new($_, $remote, "out"))
|
if ($i -lt $remote.kind.vban.out) {
|
||||||
|
[void]$outstream.Add([VbanOutAudio]::new($i, $remote))
|
||||||
|
}
|
||||||
|
elseif ($i -lt ($remote.kind.vban.out + $remote.kind.vban.midi)) {
|
||||||
|
[void]$outstream.Add([VbanOutMidi]::new($i, $remote))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[void]$outstream.Add([VbanOutVideo]::new($i, $remote))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$CustomObject = [pscustomobject]@{
|
$CustomObject = [pscustomobject]@{
|
||||||
@@ -204,11 +214,25 @@ function Make_Vban ([Object]$remote) {
|
|||||||
|
|
||||||
$CustomObject | Add-Member ScriptProperty 'enable' `
|
$CustomObject | Add-Member ScriptProperty 'enable' `
|
||||||
{
|
{
|
||||||
return Write-Warning ("ERROR: vban.enable is write only")
|
return [bool]( Param_Get -PARAM 'vban.enable' )
|
||||||
} `
|
} `
|
||||||
{
|
{
|
||||||
param([bool]$arg)
|
param([bool]$arg)
|
||||||
Param_Set -PARAM 'vban.Enable' -Value $(if ($arg) { 1 } else { 0 })
|
Param_Set -PARAM 'vban.enable' -Value $(if ($arg) { 1 } else { 0 })
|
||||||
|
}
|
||||||
|
|
||||||
|
$CustomObject | Add-Member ScriptProperty 'port' `
|
||||||
|
{
|
||||||
|
return [int]( Param_Get -PARAM 'vban.instream[0].port' )
|
||||||
|
} `
|
||||||
|
{
|
||||||
|
param([int]$arg)
|
||||||
|
if ($arg -ge 1024 -and $arg -le 65535) {
|
||||||
|
Param_Set -PARAM 'vban.instream[0].port' -Value $arg
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ('Expected value from 1024 to 65535')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$CustomObject
|
$CustomObject
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,13 +6,13 @@ Describe -Tag 'lower', -TestName 'All Lower Tests' {
|
|||||||
Describe 'Macrobutton Tests' -ForEach @(
|
Describe 'Macrobutton Tests' -ForEach @(
|
||||||
@{ Value = 1; Expected = 1 }
|
@{ Value = 1; Expected = 1 }
|
||||||
@{ Value = 0; Expected = 0 }
|
@{ Value = 0; Expected = 0 }
|
||||||
){
|
) {
|
||||||
Context 'buttons 0, 69' -ForEach @(
|
Context 'buttons 0, 69' -ForEach @(
|
||||||
@{ Index = 0 }, @{ Index = 69 }
|
@{ Index = 0 }, @{ Index = 69 }
|
||||||
){
|
) {
|
||||||
Context 'state, stateonly and trigger' -ForEach @(
|
Context 'state, stateonly and trigger' -ForEach @(
|
||||||
@{ Mode = 1 }, @{ Mode = 2 }, @{ Mode = 3 }
|
@{ Mode = 1 }, @{ Mode = 2 }, @{ Mode = 3 }
|
||||||
){
|
) {
|
||||||
It "Should set and get macrobutton[$index] State" {
|
It "Should set and get macrobutton[$index] State" {
|
||||||
MB_Set -ID $index -SET $value -MODE $mode
|
MB_Set -ID $index -SET $value -MODE $mode
|
||||||
MB_Get -ID $index -MODE $mode | Should -Be $expected
|
MB_Get -ID $index -MODE $mode | Should -Be $expected
|
||||||
@@ -24,13 +24,13 @@ Describe -Tag 'lower', -TestName 'All Lower Tests' {
|
|||||||
Describe 'Set and Get Param Float Tests' -ForEach @(
|
Describe 'Set and Get Param Float Tests' -ForEach @(
|
||||||
@{ Value = 1; Expected = 1 }
|
@{ Value = 1; Expected = 1 }
|
||||||
@{ Value = 0; Expected = 0 }
|
@{ Value = 0; Expected = 0 }
|
||||||
){
|
) {
|
||||||
Context 'Strip, one physical one virtual' -ForEach @(
|
Context 'Strip, one physical one virtual' -ForEach @(
|
||||||
@{ Index = $phys_in }, @{ Index = $virt_in }
|
@{ Index = $phys_in }, @{ Index = $virt_in }
|
||||||
){
|
) {
|
||||||
Context 'mute, mono, A1, B2' -ForEach @(
|
Context 'mute, mono, A1, B2' -ForEach @(
|
||||||
@{ param = "mute" }, @{ param = "A1" }
|
@{ param = 'mute' }, @{ param = 'A1' }
|
||||||
){
|
) {
|
||||||
It "Should set Strip[0].$param to 1" {
|
It "Should set Strip[0].$param to 1" {
|
||||||
Param_Set -PARAM "Strip[$index].$param" -VALUE $value
|
Param_Set -PARAM "Strip[$index].$param" -VALUE $value
|
||||||
Param_Get -PARAM "Strip[$index].$param" | Should -Be $expected
|
Param_Get -PARAM "Strip[$index].$param" | Should -Be $expected
|
||||||
@@ -42,10 +42,10 @@ Describe -Tag 'lower', -TestName 'All Lower Tests' {
|
|||||||
Describe 'Set and Get Param String Tests' -ForEach @(
|
Describe 'Set and Get Param String Tests' -ForEach @(
|
||||||
@{ Value = 'test0'; Expected = 'test0' }
|
@{ Value = 'test0'; Expected = 'test0' }
|
||||||
@{ Value = 'test1'; Expected = 'test1' }
|
@{ Value = 'test1'; Expected = 'test1' }
|
||||||
){
|
) {
|
||||||
Context 'Strip, one physical one virtual' -ForEach @(
|
Context 'Strip, one physical one virtual' -ForEach @(
|
||||||
@{ Index = $phys_in }, @{ Index = $virt_in }
|
@{ Index = $phys_in }, @{ Index = $virt_in }
|
||||||
){
|
) {
|
||||||
It "Should set Strip[$index].Label to $value" {
|
It "Should set Strip[$index].Label to $value" {
|
||||||
Param_Set -PARAM "Strip[$index].Label" -VALUE $value
|
Param_Set -PARAM "Strip[$index].Label" -VALUE $value
|
||||||
Param_Get -PARAM "Strip[$index].Label" -IS_STRING $true | Should -Be $expected
|
Param_Get -PARAM "Strip[$index].Label" -IS_STRING $true | Should -Be $expected
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
Param([String]$tag, [Int]$num = 1, [switch]$log, [string]$kind = "potato")
|
|
||||||
Import-Module .\lib\Voicemeeter.psm1
|
|
||||||
|
|
||||||
Function ParseLog {
|
|
||||||
Param([String]$logfile)
|
|
||||||
$summary_file = Join-Path $PSScriptRoot "_summary.log"
|
|
||||||
if (Test-Path $summary_file) { Clear-Content $summary_file }
|
|
||||||
|
|
||||||
$PASSED_PATTERN = "^PassedCount\s+:\s(\d+)"
|
|
||||||
$FAILED_PATTERN = "^FailedCount\s+:\s(\d+)"
|
|
||||||
|
|
||||||
$DATA = @{
|
|
||||||
"passed" = 0
|
|
||||||
"failed" = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ForEach ($line in `
|
|
||||||
$(Get-Content -Path "${logfile}")) {
|
|
||||||
if ($line -match $PASSED_PATTERN) {
|
|
||||||
$DATA["passed"] += $Matches[1]
|
|
||||||
}
|
|
||||||
elseif ($line -match $FAILED_PATTERN) {
|
|
||||||
$DATA["failed"] += $Matches[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"=========================`n" + `
|
|
||||||
"$num tests run:`n" + `
|
|
||||||
"=========================" | Tee-Object -FilePath $summary_file -Append
|
|
||||||
$DATA | ForEach-Object { $_ } | Tee-Object -FilePath $summary_file -Append
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
$phys_in = $vmr.kind.p_in - 1
|
|
||||||
$virt_in = $vmr.kind.p_in + $vmr.kind.v_in - 1
|
|
||||||
$phys_out = $vmr.kind.p_out - 1
|
|
||||||
$virt_out = $vmr.kind.p_out + $vmr.kind.v_out - 1
|
|
||||||
$vban_in = $vmr.kind.vban_in - 1
|
|
||||||
$vban_out = $vmr.kind.vban_out - 1
|
|
||||||
|
|
||||||
# skip conditions by kind
|
|
||||||
$ifBasic = $vmr.kind.name -eq "basic"
|
|
||||||
$ifBanana = $vmr.kind.name -eq "banana"
|
|
||||||
$ifPotato = $vmr.kind.name -eq "potato"
|
|
||||||
$ifNotBasic = $vmr.kind.name -ne "basic"
|
|
||||||
$ifNotBanana = $vmr.kind.name -ne "banana"
|
|
||||||
$ifNotPotato = $vmr.kind.name -ne "potato"
|
|
||||||
|
|
||||||
$logfile = Join-Path $PSScriptRoot "_results.log"
|
|
||||||
if (Test-Path $logfile) { Clear-Content $logfile }
|
|
||||||
|
|
||||||
1..$num | ForEach-Object {
|
|
||||||
if ($log) {
|
|
||||||
"Running test $_ of $num" | Tee-Object -FilePath $logfile -Append
|
|
||||||
Invoke-Pester -Tag $tag -PassThru | Tee-Object -FilePath $logfile -Append
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
"Running test $_ of $num"
|
|
||||||
Invoke-Pester -Tag $tag -PassThru
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($log) { Parselog -logfile $logfile }
|
|
||||||
}
|
|
||||||
finally { Disconnect-Voicemeeter }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main
|
|
||||||
89
tests/run.ps1
Normal file
89
tests/run.ps1
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Target = "variablename")]
|
||||||
|
Param([String]$tag, [string]$kind = 'potato', [string]$recDir = (Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'Voicemeeter'))
|
||||||
|
Import-Module (Join-Path (Split-Path $PSScriptRoot -Parent) 'lib\Voicemeeter.psm1') -Force
|
||||||
|
|
||||||
|
|
||||||
|
function Test-RecDir ([object]$vmr, [string]$recDir) {
|
||||||
|
$prefix = 'temp'
|
||||||
|
$filetype = 'wav'
|
||||||
|
$vmr.recorder.prefix = $prefix
|
||||||
|
$vmr.recorder.filetype = $filetype
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
$start = Get-Date
|
||||||
|
$vmr.recorder.record()
|
||||||
|
Start-Sleep -Milliseconds 2000
|
||||||
|
|
||||||
|
$tmp = Get-ChildItem -Path $recDir -Filter ("{0}*.{1}" -f $prefix, $filetype) -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.LastWriteTime -gt $start } |
|
||||||
|
Sort-Object LastWriteTime -Descending |
|
||||||
|
Select-Object -First 1
|
||||||
|
|
||||||
|
if (-not $tmp) {
|
||||||
|
throw "'$filetype' file with prefix '$prefix' was not found in '$recDir'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$vmr.recorder.stop()
|
||||||
|
$vmr.recorder.eject()
|
||||||
|
Start-Sleep -Milliseconds 500
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warning "Failed to record pre-check clip: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $tmp) {
|
||||||
|
Remove-Item -Path $tmp -Force
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning "Recorder output not found at given path: $tmp"
|
||||||
|
Write-Warning "Skipping Recording/Playback tests. Provide custom path with -recDir"
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
$phys_in = $vmr.kind.p_in - 1
|
||||||
|
$virt_in = $vmr.kind.p_in + $vmr.kind.v_in - 1
|
||||||
|
$phys_out = $vmr.kind.p_out - 1
|
||||||
|
$virt_out = $vmr.kind.p_out + $vmr.kind.v_out - 1
|
||||||
|
$vban_inA = $vmr.kind.vban.in - 1
|
||||||
|
$vban_inM = $vmr.kind.vban.in + $vmr.kind.vban.midi - 1
|
||||||
|
$vban_inT = $vmr.kind.vban.in + $vmr.kind.vban.midi + $vmr.kind.vban.text - 1
|
||||||
|
$vban_outA = $vmr.kind.vban.out - 1
|
||||||
|
$vban_outM = $vmr.kind.vban.out + $vmr.kind.vban.midi - 1
|
||||||
|
$vban_outV = $vmr.kind.vban.out + $vmr.kind.vban.midi + $vmr.kind.vban.video - 1
|
||||||
|
$insert = $vmr.kind.insert - 1
|
||||||
|
$composite = $vmr.kind.composite - 1
|
||||||
|
$strip_ch = $vmr.kind.eq_ch['strip'] - 1
|
||||||
|
$bus_ch = $vmr.kind.eq_ch['bus'] - 1
|
||||||
|
$cells = $vmr.kind.cells - 1
|
||||||
|
|
||||||
|
# skip conditions by kind
|
||||||
|
$ifBasic = $vmr.kind.name -eq 'basic'
|
||||||
|
$ifNotBasic = $vmr.kind.name -ne 'basic'
|
||||||
|
$ifNotPotato = $vmr.kind.name -ne 'potato'
|
||||||
|
|
||||||
|
# recording directory: default ~/My Documents/Voicemeeter, override if custom
|
||||||
|
$recDir = [System.IO.Path]::GetFullPath($recDir)
|
||||||
|
if ($ifBasic) {
|
||||||
|
$ifCustomDir = $ifBasic # basic can't record, so skip the test
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ifCustomDir = Test-RecDir -vmr $vmr -recDir $recDir # avoid creating files we can't delete
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-Pester -Tag $tag -PassThru | Out-Null
|
||||||
|
}
|
||||||
|
finally { Disconnect-Voicemeeter }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main
|
||||||
Reference in New Issue
Block a user