mirror of
https://github.com/onyx-and-iris/voicemeeter-api-powershell.git
synced 2026-04-20 06:23:32 +00:00
Compare commits
72 Commits
46584236d4
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| f6c750fe56 | |||
| 685854c35a | |||
|
|
68cf0cef37 | ||
|
|
91e798caa1 | ||
|
|
d1dfe2de52 | ||
|
|
ed3b7be904 | ||
|
|
33dcc98c8f | ||
|
|
55ade960f2 | ||
|
|
7d9615d760 | ||
|
|
4ea371af2f | ||
|
|
6b2031de99 | ||
|
|
8d267078ff | ||
|
|
1f5b52b439 | ||
|
|
defb2b68c0 | ||
|
|
2f2d4af848 | ||
|
|
abd792acd5 | ||
| b41001f4a9 | |||
| fc75bc2020 | |||
| d51ffacfaf | |||
| fe540895b3 | |||
| 7dd4c9db24 | |||
| 3119b1080e | |||
| a45f7a93af | |||
| 0e552873f0 | |||
| 3d87f5c03f | |||
| aaa4672cbc | |||
| f5dead51df | |||
| 259c7309dc | |||
| 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 |
158
CHANGELOG.md
158
CHANGELOG.md
@@ -5,59 +5,135 @@ 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/),
|
||||
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
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
AddActionMembers now adds ScriptMethods instead of ScriptProperties:
|
||||
- See Command section of README for details on using special commands
|
||||
- See Recorder section of README for details on using playback/record actions
|
||||
|
||||
Deprecated Recorder.Loop removed: use Recorder.Mode.Loop
|
||||
Recorder.FileType changed from method to write-only property
|
||||
## [4.2.0] - 2026-03-15
|
||||
|
||||
### Added
|
||||
|
||||
- IRemote base class
|
||||
- ArrayMember classes for array-like properties
|
||||
- Patch class
|
||||
- Option class
|
||||
- Device classes
|
||||
- EQ class
|
||||
- FX class
|
||||
- Vban.port sets Vban.Instream[0].port
|
||||
- Vban Midi and Command streams
|
||||
- on, write-only
|
||||
- name, write-only
|
||||
- ip, write-only
|
||||
- Bus.Sel, Bus.Monitor, Bus.Vaio
|
||||
- Bus.Mode.Set($mode)
|
||||
- Recorder.Armedbus
|
||||
- Recorder.PreRecTime
|
||||
- Recorder.Prefix
|
||||
- Recorder.Eject() references 'Command.Eject'
|
||||
- Recorder.State
|
||||
- Command.Reset()
|
||||
- Command.Save($filepath)
|
||||
- Command.StorePreset()
|
||||
- Command.RecallPreset()
|
||||
- New Remote methods for device enumeration:
|
||||
- GetInputCount()
|
||||
- GetOutputCount()
|
||||
- GetInputDevice($index)
|
||||
- GetOutputDevice($index)
|
||||
|
||||
- New IODevice property `driver` to get the driver type of the current device (e.g. 'wdm', 'mme', etc.)
|
||||
|
||||
- New IODevice methods to get, set, or clear the current device for a strip or bus:
|
||||
- Get(): returns a PSObject with properties Driver, Name, HardwareId, and IsOutput
|
||||
- Set($device): accepts a PSObject with properties Driver, Name, and IsOutput
|
||||
- Clear()
|
||||
|
||||
## [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
|
||||
- Bus.Mono -> [int] for stereo reverse
|
||||
- Bus.Levels.Convert return type [float] -> [single] for naming consistency, no functional change
|
||||
- Meta: AddBoolMembers, AddIntMembers $arg types for consistency
|
||||
- Device: explicit $arg types for consistency
|
||||
|
||||
- Recorder.Armstrip|Armbus -> BoolArrayMember: now have .Get()
|
||||
- Cast Recorder getters to types for consistency
|
||||
- Floats getters/setters now default to two decimal places.
|
||||
- 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
|
||||
|
||||
@@ -68,8 +144,16 @@ Recorder.FileType changed from method to write-only property
|
||||
- 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
|
||||
|
||||
359
README.md
359
README.md
@@ -8,9 +8,9 @@ For past/future changes to this project refer to: [CHANGELOG](CHANGELOG.md)
|
||||
|
||||
## Tested against
|
||||
|
||||
- Basic 1.1.1.9
|
||||
- Banana 2.1.1.9
|
||||
- Potato 3.1.1.9
|
||||
- Basic 1.1.2.2
|
||||
- Banana 2.1.2.2
|
||||
- Potato 3.1.2.2
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -113,16 +113,17 @@ $vmr.Logout()
|
||||
|
||||
### Strip
|
||||
|
||||
The following strip commands are available:
|
||||
The following Strip properties are available:
|
||||
|
||||
- mute: bool
|
||||
- mono: bool
|
||||
- mc: bool
|
||||
- k: int, from 0 to 4
|
||||
- k/karaoke: int, from 0 to 4
|
||||
- solo: bool
|
||||
- A1-A5: bool
|
||||
- B1-B3: bool
|
||||
- limit: int, from -40 to 12
|
||||
- vaio: bool
|
||||
- limit: float, from -40.00 to 12.00
|
||||
- gain: float, from -60.00 to 12.00
|
||||
- label: string
|
||||
- reverb: float, from 0.00 to 10.00
|
||||
@@ -130,7 +131,7 @@ The following strip commands are available:
|
||||
- fx1: float, from 0.00 to 10.00
|
||||
- fx2: float, from 0.00 to 10.00
|
||||
- pan_x: float, from -0.50 to 0.50
|
||||
- pan_y: float, from 0.00 to 1.00
|
||||
- pan_y: float, physical: from 0.00 to 1.00, virtual: from -0.50 to 0.50
|
||||
- color_x: float, from -0.50 to 0.50
|
||||
- color_y: float, from 0.00 to 1.00
|
||||
- fx_x: float, from -0.50 to 0.50
|
||||
@@ -139,23 +140,40 @@ The following strip commands are available:
|
||||
- postdelay: bool
|
||||
- postfx1: bool
|
||||
- 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:
|
||||
|
||||
```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.
|
||||
|
||||
#### comp
|
||||
|
||||
The following strip.comp commands are available:
|
||||
The following Strip.comp properties are available:
|
||||
|
||||
- knob: float, from 0.00 to 10.00
|
||||
- gainin: float, from -24.00 to 24.00
|
||||
@@ -175,12 +193,12 @@ $vmr.strip[3].comp.attack = 8.5
|
||||
|
||||
#### gate
|
||||
|
||||
The following strip.gate commands are available:
|
||||
The following Strip.gate properties are available:
|
||||
|
||||
- knob: float, from 0.00 to 10.00
|
||||
- threshold: float, from -60.00 to -10.00
|
||||
- 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.00 to 1000.00
|
||||
- hold: float, from 0.00 to 5000.00
|
||||
- release: float, from 0.00 to 5000.00
|
||||
@@ -193,9 +211,10 @@ $vmr.strip[3].gate.threshold = -40.5
|
||||
|
||||
#### denoiser
|
||||
|
||||
The following strip.denoiser commands are available:
|
||||
The following Strip.denoiser properties are available:
|
||||
|
||||
- knob: float, from 0.00 to 10.00
|
||||
- threshold: float, from 0.00 to 10.00
|
||||
|
||||
for example:
|
||||
|
||||
@@ -203,21 +222,57 @@ for example:
|
||||
$vmr.strip[3].denoiser.knob = 5
|
||||
```
|
||||
|
||||
#### AppGain | AppMute
|
||||
#### pitch
|
||||
|
||||
- `AppGain(amount, gain)` : string, float
|
||||
- `AppMute(amount, mutestate)` : string, bool
|
||||
The following Strip.pitch properties are available:
|
||||
|
||||
- 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:
|
||||
|
||||
```powershell
|
||||
$vmr.strip[5].AppGain("Spotify", 0.5)
|
||||
$vmr.strip[5].AppMute("Spotify", $true)
|
||||
$vmr.strip[2].pitch.recallpreset(4)
|
||||
$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
|
||||
|
||||
The following strip.level commands are available:
|
||||
The following Strip.levels methods are available:
|
||||
|
||||
- PreFader()
|
||||
- PostFader()
|
||||
@@ -231,7 +286,7 @@ $vmr.strip[2].levels.PreFader() -Join ', ' | Write-Host
|
||||
|
||||
### Bus
|
||||
|
||||
The following bus commands are available:
|
||||
The following Bus properties are available:
|
||||
|
||||
- mute: bool
|
||||
- sel: bool
|
||||
@@ -253,7 +308,7 @@ $vmr.bus[3].returnreverb = 5.7
|
||||
|
||||
#### modes
|
||||
|
||||
The following bus.mode members are available:
|
||||
The following Bus.mode members are available:
|
||||
|
||||
- normal: bool
|
||||
- amix: bool
|
||||
@@ -268,22 +323,21 @@ The following bus.mode members are available:
|
||||
- lfeonly: bool
|
||||
- rearonly: bool
|
||||
|
||||
The following bus.mode commands are available:
|
||||
The following Bus.mode methods are available:
|
||||
|
||||
- Set($mode): string, sets the current bus mode
|
||||
- Get(): returns the current bus mode.
|
||||
- Set($mode) : string, sets the current bus mode
|
||||
- Get() : returns the current bus mode
|
||||
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.bus[0].mode.centeronly = $true
|
||||
|
||||
$vmr.bus[0].mode.Get()
|
||||
$vmr.bus[0].mode.Set('tvmix')
|
||||
```
|
||||
|
||||
#### levels
|
||||
|
||||
The following strip.level commands are available:
|
||||
The following Bus.levels methods are available:
|
||||
|
||||
- All()
|
||||
|
||||
@@ -295,36 +349,62 @@ $vmr.bus[2].levels.All() -Join ', ' | Write-Host
|
||||
|
||||
### 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
|
||||
|
||||
The following strip.device | bus.device commands are available:
|
||||
The following Strip.device | Bus.device properties are available:
|
||||
|
||||
- name: string
|
||||
- driver: string
|
||||
- sr: int
|
||||
- wdm: string
|
||||
- ks: string
|
||||
- mme: string
|
||||
- asio: string
|
||||
|
||||
The following Strip.device | Bus.device methods are available:
|
||||
|
||||
- Set($device) : PSObject, where device is a PSObject with properties Driver, Name, and IsOutput
|
||||
- Get() : PSObject, returns a PSObject with properties Driver, Name, HardwareId, and IsOutput
|
||||
- Clear() : Clears the currently selected device
|
||||
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.strip[0].device.wdm = "Mic|Line|Instrument 1 (Audient EVO4)"
|
||||
$vmr.bus[0].device.name
|
||||
$vmr.bus[0].device.name | Write-Host
|
||||
|
||||
$device = $vmr.strip[3].device.Get()
|
||||
$vmr.strip[1].device.Set($device) # moves the device selected for strip 4 to strip 2
|
||||
|
||||
$vmr.bus[2].device.Clear()
|
||||
```
|
||||
|
||||
name, sr are defined as read only.
|
||||
name, driver, sr are defined as read only.
|
||||
wdm, ks, mme, asio are defined as write only.
|
||||
asio only defined for Bus[0].Device
|
||||
|
||||
#### eq
|
||||
|
||||
The following strip.eq | bus.eq commands are available:
|
||||
The following Strip.eq | Bus.eq properties are available:
|
||||
|
||||
- on: bool
|
||||
- ab: bool
|
||||
|
||||
The following strip.eq | bus.eq methods are available:
|
||||
The following Strip.eq | Bus.eq methods are available:
|
||||
|
||||
- Load($filepath) : string
|
||||
- Save($filepath) : string
|
||||
@@ -336,14 +416,21 @@ $vmr.strip[0].eq.on = $true
|
||||
$vmr.bus[0].eq.ab = $false
|
||||
```
|
||||
|
||||
##### channel.cell
|
||||
##### channel
|
||||
|
||||
The following eq.channel.cell commands are available:
|
||||
The following bus.eq.channel.cell properties are available:
|
||||
|
||||
- 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 -12.00 to 12.00
|
||||
- gain: float, from -36.00 to 18.00
|
||||
- q: float, from 0.30 to 100.00
|
||||
|
||||
for example:
|
||||
@@ -353,50 +440,57 @@ $vmr.strip[2].eq.channel[1].cell[4].type = 1
|
||||
$vmr.bus[5].eq.channel[6].cell[3].on = $false
|
||||
```
|
||||
|
||||
#### FadeTo | FadeBy
|
||||
|
||||
- `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.7, 1000)
|
||||
$vmr.bus[0].FadeBy(-10, 500)
|
||||
```
|
||||
|
||||
### Macrobuttons
|
||||
|
||||
Three modes defined: state, stateonly and trigger.
|
||||
The following Button properties are available:
|
||||
|
||||
- State runs associated scripts
|
||||
- Stateonly does not run associated scripts
|
||||
- Index range (0, 69)
|
||||
- state: bool, runs associated scripts
|
||||
- stateonly: bool, does not run associated scripts
|
||||
- trigger: bool
|
||||
|
||||
```powershell
|
||||
$vmr.button[3].state = $true
|
||||
|
||||
$vmr.button[4].stateonly = $false
|
||||
|
||||
$vmr.button[5].trigger = $true
|
||||
```
|
||||
|
||||
Index range (0, 79)
|
||||
|
||||
### VBAN
|
||||
|
||||
The following vban commands are available:
|
||||
The following Vban properties are available:
|
||||
|
||||
- enable: bool
|
||||
- port: int, from 1024 - 65535
|
||||
|
||||
For each vban in/out stream the following parameters are defined:
|
||||
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
|
||||
- ip: string
|
||||
- sr: in, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||
- channel: int from 1 to 8
|
||||
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.vban.instream[0].on = $true
|
||||
$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
|
||||
@@ -404,21 +498,50 @@ For each vban in/out stream the following parameters are defined:
|
||||
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.
|
||||
|
||||
example:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.vban.enable = $true
|
||||
$vmr.vban.port = 6990
|
||||
|
||||
$vmr.vban.instream[0].on = $true
|
||||
$vmr.vban.instream[0].route = 4
|
||||
$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
|
||||
|
||||
Certain 'special' commands are defined by the API as performing actions rather than setting values.
|
||||
|
||||
The following methods are available:
|
||||
The following Command methods are available:
|
||||
|
||||
- Show()
|
||||
- Hide()
|
||||
@@ -428,15 +551,15 @@ The following methods are available:
|
||||
- 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
|
||||
- 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
|
||||
|
||||
example:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.command.Show()
|
||||
@@ -458,7 +581,7 @@ StorePreset('') and RecallPreset('') interact with the 'selected' preset. This i
|
||||
|
||||
### Fx
|
||||
|
||||
The following Fx commands are available:
|
||||
The following Fx properties are available:
|
||||
|
||||
- Reverb.on: bool
|
||||
- Reverb.ab: bool
|
||||
@@ -473,12 +596,12 @@ $vmr.fx.reverb.ab = $false
|
||||
|
||||
### Patch
|
||||
|
||||
The following Patch commands are available:
|
||||
The following Patch properties are available:
|
||||
|
||||
- postFaderComposite: bool
|
||||
- postFxInsert: bool
|
||||
|
||||
The following Patch members have .Set($val) and .Get() available:
|
||||
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
|
||||
@@ -496,7 +619,7 @@ $vmr.patch.insert[4].get()
|
||||
|
||||
### Option
|
||||
|
||||
The following Option commands are available:
|
||||
The following Option properties are available:
|
||||
|
||||
- sr: int, (32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||
- asiosr: bool
|
||||
@@ -504,21 +627,15 @@ The following Option commands are available:
|
||||
- sliderMode: bool
|
||||
- monitoringBus: int, from 0 to bus index
|
||||
|
||||
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
|
||||
$vmr.Option.sliderMode = $false # sets slider mode to absolute
|
||||
```
|
||||
|
||||
#### buffers
|
||||
|
||||
The following Option.buffer commands are available:
|
||||
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)
|
||||
@@ -532,9 +649,22 @@ $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
|
||||
|
||||
The following commands are available:
|
||||
The following Recorder properties are available:
|
||||
|
||||
- A1 - A5: bool
|
||||
- B1 - B3: bool
|
||||
@@ -549,7 +679,15 @@ The following commands are available:
|
||||
- channel: int, (2, 4, 6, 8)
|
||||
- kbps: int, (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
|
||||
|
||||
The following methods are available:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.A1 = $true
|
||||
$vmr.recorder.filetype = 'mp3'
|
||||
$vmr.recorder.kbps = 256
|
||||
```
|
||||
|
||||
The following Recorder methods are available:
|
||||
|
||||
- Play()
|
||||
- Stop()
|
||||
@@ -559,41 +697,39 @@ The following methods are available:
|
||||
- Record()
|
||||
- Pause()
|
||||
- Eject()
|
||||
- Load($filepath): string
|
||||
- GoTo($timestring): string, must match the format 'hh:mm:ss'
|
||||
- Load($filepath) : string
|
||||
- GoTo($timestring) : string, must match the format 'hh:mm:ss'
|
||||
|
||||
example:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.play()
|
||||
$vmr.recorder.A1 = $true
|
||||
|
||||
$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
|
||||
- playonload
|
||||
- loop
|
||||
- multitrack
|
||||
- recbus: bool
|
||||
- playonload: bool
|
||||
- loop: bool
|
||||
- multitrack: bool
|
||||
|
||||
example:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.mode.loop = $true
|
||||
```
|
||||
|
||||
#### ArmStrip[i]|ArmBus[i]
|
||||
#### armstrip[i]|armbus[i]
|
||||
|
||||
The following methods are available:
|
||||
The following Recorder.armstrip | Recorder.armbus methods are available:
|
||||
|
||||
- Set($val): bool
|
||||
- Set($val) : bool
|
||||
- Get()
|
||||
|
||||
example:
|
||||
for example:
|
||||
|
||||
```powershell
|
||||
$vmr.recorder.armstrip[0].Set($true)
|
||||
@@ -669,6 +805,21 @@ Access to lower level polling functions are provided with these functions:
|
||||
- `$vmr.PDirty`: Returns true if a parameter has been updated.
|
||||
- `$vmr.MDirty`: Returns true if a macrobutton has been updated.
|
||||
|
||||
Access to lower level device enumeration functions are provided with these functions:
|
||||
|
||||
- `$vmr.GetInputCount()`: Returns the number of available input devices.
|
||||
- `$vmr.GetOutputCount()`: Returns the number of available output devices.
|
||||
- `$vmr.GetInputDevice($index)`: Returns a PSObject with properties Driver, Name, HardwareId, and IsOutput for the input device at the given index.
|
||||
- `$vmr.GetOutputDevice($index)`: Returns a PSObject with properties Driver, Name, HardwareId, and IsOutput for the output device at the given index.
|
||||
|
||||
```powershell
|
||||
$count = $vmr.GetInputCount()
|
||||
for ($i = 0; $i -lt $count; $i++) {
|
||||
$device = $vmr.GetInputDevice($i)
|
||||
Write-Host "Input Device $i: $($device.Driver) - $($device.Name)"
|
||||
}
|
||||
```
|
||||
|
||||
### Errors
|
||||
|
||||
- `VMRemoteError`: Base custom error class.
|
||||
|
||||
@@ -9,3 +9,16 @@ tasks:
|
||||
cmds:
|
||||
- echo "Running tests..."
|
||||
- pwsh -c "tests\run.ps1 {{.CLI_ARGS}}"
|
||||
|
||||
bump:
|
||||
desc: 'Bump the module version in the .psd1 file. Usage: "task bump -- show" or "task bump -- [patch|minor|major]".'
|
||||
preconditions:
|
||||
- sh: 'pwsh -c "if (Get-Command bump) { exit 0 } else { exit 1 }"'
|
||||
msg: "The 'bump' command is not available. Please install the required tools to use this command."
|
||||
cmds:
|
||||
- |
|
||||
{{if eq .CLI_ARGS "show"}}
|
||||
pwsh -c "bump show -f lib/Voicemeeter.psd1 -p \"ModuleVersion\s*=\s'(\d+\.\d+\.\d+)'\""
|
||||
{{else}}
|
||||
pwsh -c "bump {{.CLI_ARGS}} -w -f lib/Voicemeeter.psd1 -p \"ModuleVersion\s*=\s'(\d+\.\d+\.\d+)'\""
|
||||
{{end}}
|
||||
|
||||
@@ -1,64 +1,129 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Command Line Interface for Voicemeeter control.
|
||||
.DESCRIPTION
|
||||
This script provides a command line interface to interact with Voicemeeter. It supports both interactive mode and scripted commands.
|
||||
Users can specify the type of Voicemeeter (banana or potato) and execute commands to get or set parameters.
|
||||
.PARAMETER help
|
||||
Displays help information.
|
||||
.PARAMETER interactive
|
||||
Starts the CLI in interactive mode.
|
||||
.PARAMETER kind
|
||||
Specifies the type of Voicemeeter to connect to (banana or potato). Default is 'banana'.
|
||||
.PARAMETER script
|
||||
A list of commands to execute in sequence.
|
||||
.EXAMPLE
|
||||
.\CLI.ps1 -interactive -kind banana
|
||||
Starts the CLI in interactive mode for Voicemeeter Banana.
|
||||
.EXAMPLE
|
||||
.\CLI.ps1 -script "Strip[0].Gain=3", "!Bus[1].Mute", "Bus[0].Gain"
|
||||
Executes a series of commands: sets Strip 0 Gain to 3, toggles Bus 1 Mute, and retrieves Bus 0 Gain.
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
[switch]$help,
|
||||
[switch]$interactive,
|
||||
[ValidateSet('basic', 'banana', 'potato')]
|
||||
[String]$kind = 'banana',
|
||||
[String[]]$script = @()
|
||||
)
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
|
||||
function get-value {
|
||||
param([object]$vmr, [string]$line)
|
||||
if ($help -or ($script.Count -eq 0 -and -not $interactive)) {
|
||||
Write-Host 'Voicemeeter CLI'
|
||||
Write-Host ''
|
||||
Write-Host 'Usage:'
|
||||
Write-Host ' CLI.ps1 [-interactive] [-kind <basic|banana|potato>] [-script <command1>, <command2>, ...]'
|
||||
Write-Host ''
|
||||
Write-Host 'Options:'
|
||||
Write-Host ' -help Display this help message.'
|
||||
Write-Host ' -interactive Start in interactive mode.'
|
||||
Write-Host ' -kind <type> Specify the Voicemeeter type (basic, banana or potato). Default is banana.'
|
||||
Write-Host ' -script <commands> Provide a list of commands to execute in sequence.'
|
||||
Write-Host ''
|
||||
Write-Host 'Commands can be of the form:'
|
||||
Write-Host ' Parameter=Value Set a parameter to a specific value.'
|
||||
Write-Host ' !Parameter Toggle a boolean parameter.'
|
||||
Write-Host ' Parameter Get the current value of a parameter.'
|
||||
exit 0
|
||||
}
|
||||
|
||||
function Get-ParameterValue {
|
||||
param(
|
||||
[object]$vmr,
|
||||
[string]$Parameter
|
||||
)
|
||||
|
||||
try {
|
||||
$retval = $vmr.Getter($line)
|
||||
$retval = $vmr.Getter($Parameter)
|
||||
}
|
||||
catch {
|
||||
$retval = $vmr.Getter_String($line)
|
||||
$retval = $vmr.Getter_String($Parameter)
|
||||
}
|
||||
$retval
|
||||
}
|
||||
|
||||
function msgHandler {
|
||||
param([object]$vmr, [string]$line)
|
||||
$line + ' passed to handler' | Write-Debug
|
||||
if ($line[0] -eq '!') {
|
||||
'Toggling ' + $line.substring(1) | Write-Debug
|
||||
$retval = get-value -vmr $vmr -line $line.substring(1)
|
||||
$vmr.Setter($line.substring(1), 1 - $retval)
|
||||
|
||||
function Invoke-VoicemeeterCLICommand {
|
||||
param(
|
||||
[object]$vmr,
|
||||
[string]$Command
|
||||
)
|
||||
|
||||
# Toggle command
|
||||
if ($Command[0] -eq '!') {
|
||||
$parameter = $Command.Substring(1).Trim()
|
||||
$currentValue = Get-ParameterValue -vmr $vmr -Parameter $parameter
|
||||
|
||||
if ($currentValue -ne 0 -and $currentValue -ne 1) {
|
||||
throw "Cannot toggle non-boolean parameter '$parameter' with value '$currentValue'"
|
||||
}
|
||||
|
||||
$newValue = 1 - $currentValue
|
||||
$vmr.SendText("$parameter=$newValue")
|
||||
Write-Host "Toggled $parameter to $newValue"
|
||||
}
|
||||
elseif ($line.Contains('=')) {
|
||||
"Setting $line" | Write-Debug
|
||||
$vmr.SendText($line)
|
||||
# Set command
|
||||
elseif ($Command.Contains('=')) {
|
||||
$vmr.SendText("$Command")
|
||||
Write-Host "Set $Command"
|
||||
}
|
||||
# Get command
|
||||
else {
|
||||
$parameter = $Command.Trim()
|
||||
$value = Get-ParameterValue -vmr $vmr -Parameter $parameter
|
||||
Write-Host "$parameter = $value"
|
||||
}
|
||||
}
|
||||
|
||||
function Start-VoicemeeterCLI {
|
||||
param(
|
||||
[object]$vmr
|
||||
)
|
||||
|
||||
Write-Host "Connected to Voicemeeter. Type 'Q' to quit." -ForegroundColor Green
|
||||
while (($CommandFromInput = Read-Host 'command') -ne 'Q') {
|
||||
try {
|
||||
Invoke-VoicemeeterCLICommand -vmr $vmr -Command $CommandFromInput
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error: $_" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$vmr = Connect-Voicemeeter -Kind $kind
|
||||
|
||||
if ($interactive) {
|
||||
Start-VoicemeeterCLI -vmr $vmr
|
||||
}
|
||||
else {
|
||||
"Getting $line" | Write-Debug
|
||||
$retval = get-value -vmr $vmr -line $line
|
||||
$line + ' = ' + $retval | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
function read-hostuntilempty {
|
||||
param([object]$vmr)
|
||||
while (($line = Read-Host) -cne [string]::Empty) { msgHandler -vmr $vmr -line $line }
|
||||
}
|
||||
|
||||
|
||||
function main {
|
||||
[object]$vmr
|
||||
|
||||
try {
|
||||
$vmr = Connect-Voicemeeter -Kind $kind
|
||||
|
||||
if ($interactive) {
|
||||
'Press <Enter> to exit' | Write-Host
|
||||
read-hostuntilempty -vmr $vmr
|
||||
return
|
||||
}
|
||||
$script | ForEach-Object {
|
||||
msgHandler -vmr $vmr -line $_
|
||||
foreach ($command in $script) {
|
||||
Invoke-VoicemeeterCLICommand -vmr $vmr -Command $command
|
||||
}
|
||||
}
|
||||
finally { Disconnect-Voicemeeter }
|
||||
}
|
||||
|
||||
main
|
||||
finally { Disconnect-Voicemeeter }
|
||||
@@ -1,32 +1,39 @@
|
||||
## About
|
||||
|
||||
A simple voicemeeter-cli script. Offers ability to toggle, get and set parameters.
|
||||
A basic command-line interface
|
||||
|
||||
## Use
|
||||
|
||||
Toggle with `!` prefix, get by excluding `=` and set by including `=`. Mix and match arguments.
|
||||
```console
|
||||
Voicemeeter CLI
|
||||
|
||||
You may pass the following optional flags:
|
||||
Usage:
|
||||
CLI.ps1 [-interactive] [-kind <basic|banana|potato>] [-script <command1>, <command2>, ...]
|
||||
|
||||
- -o: (-output) to toggle console output.
|
||||
- -i: (-interactive) to toggle interactive mode.
|
||||
- -k: (-kind) to set the kind of Voicemeeter. Defaults to banana.
|
||||
- -s: (script) a string array, one string for each command.
|
||||
Options:
|
||||
-help Display this help message.
|
||||
-interactive Start in interactive mode.
|
||||
-kind <type> Specify the Voicemeeter type (basic, banana or potato). Default is banana.
|
||||
-script <commands> Provide a list of commands to execute in sequence.
|
||||
|
||||
Commands can be of the form:
|
||||
Parameter=Value Set a parameter to a specific value.
|
||||
!Parameter Toggle a boolean parameter.
|
||||
Parameter Get the current value of a parameter.
|
||||
```
|
||||
|
||||
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"`
|
||||
|
||||
Expected output:
|
||||
|
||||
```powershell
|
||||
.\CLI.ps1 -script strip[0].mute, !strip[0].mute, strip[0].mute, bus[2].eq.on=1, command.lock=1
|
||||
```
|
||||
Getting strip[0].mute
|
||||
strip[0].mute = 0
|
||||
Toggling strip[0].mute
|
||||
Getting strip[0].mute
|
||||
|
||||
should produce the output:
|
||||
|
||||
```console
|
||||
strip[0].mute = 1
|
||||
Setting bus[2].eq.on=1
|
||||
Setting command.lock=1
|
||||
```
|
||||
|
||||
If running in interactive mode press `<Enter>` to exit.
|
||||
Toggled strip[0].mute to 0
|
||||
strip[0].mute = 0
|
||||
Set bus[2].eq.on=1
|
||||
Set command.lock=1
|
||||
```
|
||||
@@ -1,47 +0,0 @@
|
||||
<#
|
||||
1) Loop through an array of bus objects.
|
||||
2) Mute first unmuted bus
|
||||
3) If next bus in array exists, unmute it, otherwise clear unmuted variable.
|
||||
4) If every bus in array is muted, unmute the first bus specified in array.
|
||||
|
||||
Credits go to @bobsupercow
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
|
||||
try {
|
||||
$vmr = Connect-Voicemeeter -Kind 'potato'
|
||||
|
||||
$buses = @($vmr.bus[1], $vmr.bus[2], $vmr.bus[4], $vmr.bus[6])
|
||||
"Buses in selection: $($buses)"
|
||||
$unmutedIndex = $null
|
||||
|
||||
# 1)
|
||||
'Cycling through bus selection to check for first unmuted Bus...' | Write-Host
|
||||
foreach ($bus in $buses) {
|
||||
# 2)
|
||||
if (-not $bus.mute) {
|
||||
"Bus $($bus.index) is unmuted... muting it" | Write-Host
|
||||
$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
|
||||
}
|
||||
|
||||
}
|
||||
finally { Disconnect-Voicemeeter }
|
||||
70
examples/nextbus/Rotate-Buses.ps1
Normal file
70
examples/nextbus/Rotate-Buses.ps1
Normal file
@@ -0,0 +1,70 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Rotates through specified Voicemeeter buses, unmuting one at a time.
|
||||
.DESCRIPTION
|
||||
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,
|
||||
while all other specified buses are muted. The user can exit the rotation by typing 'Q'.
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
|
||||
class BusRotator {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Class to manage rotating through Voicemeeter buses.
|
||||
#>
|
||||
[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 {
|
||||
$vmr = Connect-Voicemeeter -Kind 'potato'
|
||||
|
||||
# Mute all buses initially
|
||||
foreach ($bus in $vmr.bus) {
|
||||
$bus.mute = $true
|
||||
}
|
||||
|
||||
$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 }
|
||||
293
examples/obs/Sync-OBS-Voicemeeter.ps1
Normal file
293
examples/obs/Sync-OBS-Voicemeeter.ps1
Normal file
@@ -0,0 +1,293 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Synchronizes OBS Studio scene changes with Voicemeeter audio settings.
|
||||
|
||||
.DESCRIPTION
|
||||
This script monitors OBS Studio for scene changes via WebSocket connection and
|
||||
automatically adjusts Voicemeeter audio settings based on the active scene.
|
||||
|
||||
.PARAMETER ConfigPath
|
||||
Path to the configuration file. Defaults to 'config.psd1' in the script directory.
|
||||
|
||||
.PARAMETER VoicemeeterKind
|
||||
Type of Voicemeeter to connect to. Defaults to 'basic'.
|
||||
|
||||
.EXAMPLE
|
||||
.\Vm-Obs-Sync.ps1
|
||||
|
||||
.EXAMPLE
|
||||
.\Vm-Obs-Sync.ps1 -ConfigPath "C:\myconfig.psd1" -VoicemeeterKind "banana"
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$ConfigPath = (Join-Path $PSScriptRoot 'config.psd1'),
|
||||
[ValidateSet('basic', 'banana', 'potato')]
|
||||
[string]$VoicemeeterKind = 'basic'
|
||||
)
|
||||
|
||||
#Requires -Modules obs-powershell
|
||||
|
||||
# Import required modules
|
||||
try {
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
Import-Module obs-powershell
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to import required modules: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Script-level variables
|
||||
$script:vmr = $null
|
||||
$script:obsJob = $null
|
||||
$script:shouldExit = $false
|
||||
|
||||
#region Helper Functions
|
||||
|
||||
function Write-Log {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Writes timestamped log messages to the console.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory, ValueFromPipeline)]
|
||||
[string]$Message,
|
||||
[ValidateSet('Info', 'Warning', 'Error')]
|
||||
[string]$Level = 'Info'
|
||||
)
|
||||
|
||||
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
|
||||
$logMessage = "[$timestamp] [$Level] $Message"
|
||||
|
||||
switch ($Level) {
|
||||
'Info' { Write-Information $logMessage -InformationAction Continue }
|
||||
'Warning' { Write-Warning $logMessage }
|
||||
'Error' { Write-Error $logMessage }
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ConnectionConfig {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Loads OBS connection configuration from file.
|
||||
#>
|
||||
param([string]$Path = $ConfigPath)
|
||||
|
||||
try {
|
||||
if (-not (Test-Path $Path)) {
|
||||
throw "Configuration file not found: $Path"
|
||||
}
|
||||
|
||||
$config = Import-PowerShellDataFile -Path $Path -ErrorAction Stop
|
||||
|
||||
# Validate required properties
|
||||
$requiredProperties = @('host', 'port', 'password')
|
||||
foreach ($prop in $requiredProperties) {
|
||||
if (-not $config.ContainsKey($prop)) {
|
||||
throw "Missing required configuration property: $prop"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Log "Configuration loaded successfully from: $Path"
|
||||
return $config
|
||||
}
|
||||
catch {
|
||||
Write-Log "Failed to load configuration: $($_.Exception.Message)" -Level Error
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-Connections {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Initializes connections to Voicemeeter and OBS.
|
||||
#>
|
||||
try {
|
||||
$script:vmr = Connect-Voicemeeter -Kind $VoicemeeterKind -ErrorAction Stop
|
||||
Write-Log 'Voicemeeter connection established'
|
||||
|
||||
$obsConfig = Get-ConnectionConfig
|
||||
|
||||
|
||||
$webSocketUri = "ws://$($obsConfig.host):$($obsConfig.port)"
|
||||
$script:obsJob = Watch-OBS -WebSocketURI $webSocketUri -WebSocketToken $obsConfig.password -ErrorAction Stop
|
||||
Write-Log "OBS connection at $webSocketUri established"
|
||||
}
|
||||
catch {
|
||||
Write-Log "Failed to initialize connections: $($_.Exception.Message)" -Level Error
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Disconnect-All {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Safely disconnects from all services.
|
||||
#>
|
||||
Write-Log 'Cleaning up connections...'
|
||||
|
||||
try {
|
||||
if ($script:obsJob) {
|
||||
Remove-Job -Job $script:obsJob -Force -ErrorAction SilentlyContinue
|
||||
Disconnect-OBS -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error disconnecting from OBS: $($_.Exception.Message)" -Level Warning
|
||||
}
|
||||
|
||||
try {
|
||||
if ($script:vmr) {
|
||||
Disconnect-Voicemeeter -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error disconnecting from Voicemeeter: $($_.Exception.Message)" -Level Warning
|
||||
}
|
||||
|
||||
Write-Log 'Cleanup completed'
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
function Invoke-CurrentProgramSceneChanged {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Handles OBS scene change events.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[System.Object]$EventData
|
||||
)
|
||||
|
||||
if (-not $EventData.sceneName) {
|
||||
Write-Log 'Scene change event received but no scene name provided' -Level Warning
|
||||
return
|
||||
}
|
||||
|
||||
Write-Log "Scene changed to: $($EventData.sceneName)"
|
||||
|
||||
try {
|
||||
switch ($EventData.sceneName) {
|
||||
'START' {
|
||||
Write-Log 'Toggling mute for strip 0'
|
||||
$script:vmr.strip[0].mute = !$script:vmr.strip[0].mute
|
||||
}
|
||||
'BRB' {
|
||||
Write-Log 'Setting gain to -8.3dB for strip 0'
|
||||
$script:vmr.strip[0].gain = -8.3
|
||||
}
|
||||
'END' {
|
||||
Write-Log 'Enabling mono for strip 0'
|
||||
$script:vmr.strip[0].mono = $true
|
||||
}
|
||||
'LIVE' {
|
||||
Write-Log 'Setting color_x to 0.3 for strip 0'
|
||||
$script:vmr.strip[0].color_x = 0.3
|
||||
}
|
||||
default {
|
||||
Write-Log "Unknown scene '$($EventData.sceneName)'. Expected: START, BRB, END, or LIVE" -Level Warning
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error processing scene change: $($_.Exception.Message)" -Level Error
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-ExitStarted {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Handles OBS exit events.
|
||||
#>
|
||||
param([System.Object]$EventData)
|
||||
|
||||
Write-Log 'OBS shutdown detected - initiating graceful exit'
|
||||
$script:shouldExit = $true
|
||||
}
|
||||
|
||||
function Invoke-EventDispatcher {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Dispatches OBS events to appropriate handlers.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[System.Object]$EventData
|
||||
)
|
||||
|
||||
if (-not $EventData.eventType) {
|
||||
Write-Log 'Event received without eventType property' -Level Warning
|
||||
return
|
||||
}
|
||||
|
||||
$handlerName = "Invoke-$($EventData.eventType)"
|
||||
|
||||
if (Get-Command $handlerName -ErrorAction SilentlyContinue) {
|
||||
try {
|
||||
& $handlerName -EventData $EventData.eventData
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error in event handler '$handlerName': $($_.Exception.Message)" -Level Error
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Log "No handler found for event type: $($EventData.eventType)" -Level Warning
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Main Execution
|
||||
|
||||
function Start-VoicemeeterObsSync {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Main execution function for the sync process.
|
||||
#>
|
||||
Write-Log 'Starting Voicemeeter-OBS synchronization service'
|
||||
|
||||
try {
|
||||
Initialize-Connections
|
||||
|
||||
Write-Log 'Monitoring OBS events... Press Ctrl+C to stop'
|
||||
|
||||
while (-not $script:shouldExit) {
|
||||
try {
|
||||
$obsEvents = Receive-Job -Job $script:obsJob -ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($obsEvent in $obsEvents) {
|
||||
if ($obsEvent.MessageData.op -eq 5) {
|
||||
Invoke-EventDispatcher -EventData $obsEvent.MessageData.d
|
||||
}
|
||||
}
|
||||
|
||||
Start-Sleep -Milliseconds 100
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error processing OBS events: $($_.Exception.Message)" -Level Error
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log "Fatal error: $($_.Exception.Message)" -Level Error
|
||||
exit 1
|
||||
}
|
||||
finally {
|
||||
Disconnect-All
|
||||
}
|
||||
|
||||
Write-Log 'Voicemeeter-OBS synchronization service stopped'
|
||||
}
|
||||
|
||||
# Handle Ctrl+C gracefully
|
||||
$null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {
|
||||
$script:shouldExit = $true
|
||||
}
|
||||
|
||||
Start-VoicemeeterObsSync
|
||||
|
||||
#endregion
|
||||
@@ -1,68 +0,0 @@
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
Import-Module ..\..\lib\Voicemeeter.psm1
|
||||
Import-Module obs-powershell
|
||||
|
||||
function CurrentProgramSceneChanged {
|
||||
param([System.Object]$data)
|
||||
Write-Host 'Switched to scene', $data.sceneName
|
||||
|
||||
switch ($data.sceneName) {
|
||||
'START' {
|
||||
$vmr.strip[0].mute = !$vmr.strip[0].mute
|
||||
}
|
||||
'BRB' {
|
||||
$vmr.strip[0].gain = -8.3
|
||||
}
|
||||
'END' {
|
||||
$vmr.strip[0].mono = $true
|
||||
}
|
||||
'LIVE' {
|
||||
$vmr.strip[0].color_x = 0.3
|
||||
}
|
||||
default { 'Expected START, BRB, END or LIVE scene' | Write-Warning; return }
|
||||
}
|
||||
}
|
||||
|
||||
function ExitStarted {
|
||||
param([System.Object]$data)
|
||||
'OBS shutdown has begun!' | Write-Host
|
||||
break
|
||||
}
|
||||
|
||||
function eventHandler($data) {
|
||||
if (Get-Command $data.eventType -ErrorAction SilentlyContinue) {
|
||||
& $data.eventType -data $data.eventData
|
||||
}
|
||||
}
|
||||
|
||||
function ConnFromFile {
|
||||
$configpath = Join-Path $PSScriptRoot 'config.psd1'
|
||||
return Import-PowerShellDataFile -Path $configpath
|
||||
}
|
||||
|
||||
function main {
|
||||
$vmr = Connect-Voicemeeter -Kind 'basic'
|
||||
|
||||
$conn = ConnFromFile
|
||||
$job = Watch-OBS -WebSocketURI "ws://$($conn.host):$($conn.port)" -WebSocketToken $conn.password
|
||||
|
||||
try {
|
||||
while ($true) {
|
||||
Receive-Job -Job $job | ForEach-Object {
|
||||
$data = $_.MessageData
|
||||
|
||||
if ($data.op -eq 5) {
|
||||
eventHandler($data.d)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Disconnect-OBS
|
||||
Disconnect-Voicemeeter
|
||||
}
|
||||
}
|
||||
|
||||
main
|
||||
@@ -4,8 +4,7 @@
|
||||
. $PSScriptRoot\kinds.ps1
|
||||
. $PSScriptRoot\iremote.ps1
|
||||
. $PSScriptRoot\arraymember.ps1
|
||||
. $PSScriptRoot\device.ps1
|
||||
. $PSScriptRoot\eq.ps1
|
||||
. $PSScriptRoot\io.ps1
|
||||
. $PSScriptRoot\strip.ps1
|
||||
. $PSScriptRoot\bus.ps1
|
||||
. $PSScriptRoot\macrobuttons.ps1
|
||||
@@ -76,6 +75,22 @@ class Remote {
|
||||
[void] PDirty() { P_Dirty }
|
||||
|
||||
[void] MDirty() { M_Dirty }
|
||||
|
||||
[int] GetOutputCount() {
|
||||
return Device_Count -IS_OUT $true
|
||||
}
|
||||
|
||||
[int] GetInputCount() {
|
||||
return Device_Count
|
||||
}
|
||||
|
||||
[PSObject] GetOutputDevice([int]$index) {
|
||||
return Device_Desc -INDEX $index -IS_OUT $true
|
||||
}
|
||||
|
||||
[PSObject] GetInputDevice([int]$index) {
|
||||
return Device_Desc -INDEX $index
|
||||
}
|
||||
}
|
||||
|
||||
class RemoteBasic : Remote {
|
||||
|
||||
55
lib/base.ps1
55
lib/base.ps1
@@ -225,4 +225,59 @@ function Get_Level {
|
||||
throw [CAPIError]::new($retval, 'VBVMR_GetLevel')
|
||||
}
|
||||
[float]$ptr
|
||||
}
|
||||
|
||||
function Device_Count {
|
||||
param(
|
||||
[bool]$IS_OUT = $false
|
||||
)
|
||||
if ($IS_OUT) {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Output_GetDeviceNumber()
|
||||
if ($retval -lt 0) {
|
||||
throw [CAPIError]::new($retval, 'VBVMR_Output_GetDeviceNumber')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Input_GetDeviceNumber()
|
||||
if ($retval -lt 0) {
|
||||
throw [CAPIError]::new($retval, 'VBVMR_Input_GetDeviceNumber')
|
||||
}
|
||||
}
|
||||
$retval
|
||||
}
|
||||
|
||||
function Device_Desc {
|
||||
param(
|
||||
[int]$INDEX, [bool]$IS_OUT = $false
|
||||
)
|
||||
$driver = 0
|
||||
$name = [System.Byte[]]::new(512)
|
||||
$hardwareid = [System.Byte[]]::new(512)
|
||||
|
||||
if ($IS_OUT) {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Output_GetDeviceDescA($INDEX, [ref]$driver, $name, $hardwareid)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, 'VBVMR_Output_GetDeviceDescA')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$retval = [int][Voicemeeter.Remote]::VBVMR_Input_GetDeviceDescA($INDEX, [ref]$driver, $name, $hardwareid)
|
||||
if ($retval -notin @(0)) {
|
||||
throw [CAPIError]::new($retval, 'VBVMR_Input_GetDeviceDescA')
|
||||
}
|
||||
}
|
||||
|
||||
$drivers = @{
|
||||
1 = 'mme'
|
||||
3 = 'wdm'
|
||||
4 = 'ks'
|
||||
5 = 'asio'
|
||||
}
|
||||
|
||||
[PSCustomObject]@{
|
||||
Driver = $drivers[$driver]
|
||||
Name = [System.Text.Encoding]::ASCII.GetString($name).Trim([char]0)
|
||||
HardwareId = [System.Text.Encoding]::ASCII.GetString($hardwareid).Trim([char]0)
|
||||
IsOutput = $IS_OUT
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,15 @@ function Setup_DLL {
|
||||
|
||||
[DllImport(@"$dll")]
|
||||
public static extern int VBVMR_GetLevel(Int64 mode, Int64 index, ref float ptr);
|
||||
|
||||
[DllImport(@"$dll")]
|
||||
public static extern int VBVMR_Output_GetDeviceNumber();
|
||||
[DllImport(@"$dll")]
|
||||
public static extern int VBVMR_Input_GetDeviceNumber();
|
||||
[DllImport(@"$dll")]
|
||||
public static extern int VBVMR_Output_GetDeviceDescA(Int64 index, ref int type, byte[] name, byte[] hardwareid);
|
||||
[DllImport(@"$dll")]
|
||||
public static extern int VBVMR_Input_GetDeviceDescA(Int64 index, ref int type, byte[] name, byte[] hardwareid);
|
||||
"@
|
||||
|
||||
Add-Type -MemberDefinition $Signature -Name Remote -Namespace Voicemeeter -PassThru | Out-Null
|
||||
|
||||
56
lib/bus.ps1
56
lib/bus.ps1
@@ -1,13 +1,12 @@
|
||||
class Bus : IRemote {
|
||||
class Bus : IOControl {
|
||||
[Object]$mode
|
||||
[Object]$eq
|
||||
[Object]$levels
|
||||
|
||||
Bus ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('mute', 'sel', 'monitor')
|
||||
AddBoolMembers -PARAMS @('sel', 'monitor')
|
||||
AddIntMembers -PARAMS @('mono')
|
||||
AddStringMembers -PARAMS @('label')
|
||||
AddFloatMembers -PARAMS @('gain', 'returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
|
||||
AddFloatMembers -PARAMS @('returnreverb', 'returndelay', 'returnfx1', 'returnfx2')
|
||||
|
||||
$this.mode = [BusMode]::new($index, $remote)
|
||||
$this.eq = [BusEq]::new($index, $remote)
|
||||
@@ -17,17 +16,9 @@ class Bus : IRemote {
|
||||
[string] identifier () {
|
||||
return 'Bus[' + $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 BusLevels : IRemote {
|
||||
class BusLevels : IOLevels {
|
||||
[int]$init
|
||||
[int]$offset
|
||||
|
||||
@@ -36,23 +27,6 @@ class BusLevels : IRemote {
|
||||
$this.offset = 8
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] All() {
|
||||
return $this.Getter(3)
|
||||
}
|
||||
@@ -93,7 +67,7 @@ class BusMode : IRemote {
|
||||
}
|
||||
}
|
||||
|
||||
class BusEq : Eq {
|
||||
class BusEq : IOEq {
|
||||
BusEq ([int]$index, [Object]$remote) : base ($index, $remote, 'Bus') {
|
||||
}
|
||||
|
||||
@@ -122,10 +96,10 @@ class VirtualBus : Bus {
|
||||
}
|
||||
}
|
||||
|
||||
class BusDevice : Device {
|
||||
BusDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class BusDevice : IODevice {
|
||||
BusDevice ([int]$index, [Object]$remote) : base ($index, $remote, 'Output') {
|
||||
if ($this.index -eq 0) {
|
||||
$this.AddASIO()
|
||||
AddStringMembers -PARAMS @('asio') -WriteOnly
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,14 +107,12 @@ class BusDevice : Device {
|
||||
return 'Bus[' + $this.index + '].Device'
|
||||
}
|
||||
|
||||
hidden [void] AddASIO () {
|
||||
Add-Member -InputObject $this -MemberType ScriptProperty -Name 'asio' `
|
||||
-Value {
|
||||
return Write-Warning ("ERROR: $($this.identifier()).asio is write only")
|
||||
} -SecondValue {
|
||||
param([string]$arg)
|
||||
return $this.Setter('asio', $arg)
|
||||
} -Force
|
||||
[int] EnumCount () {
|
||||
return $this.remote.GetOutputCount()
|
||||
}
|
||||
|
||||
[PSObject] EnumDevice ([int]$eIndex) {
|
||||
return $this.remote.GetOutputDevice($eIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
class Device : IRemote {
|
||||
Device ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
}
|
||||
|
||||
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' `
|
||||
{
|
||||
[int]$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([string]$arg)
|
||||
return $this.Setter('wdm', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_ks = $($this | Add-Member ScriptProperty 'ks' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).ks is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
return $this.Setter('ks', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_mme = $($this | Add-Member ScriptProperty 'mme' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).mme is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
return $this.Setter('mme', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
60
lib/eq.ps1
60
lib/eq.ps1
@@ -1,60 +0,0 @@
|
||||
class Eq : IRemote {
|
||||
[System.Collections.ArrayList]$channel
|
||||
[string]$kindOfEq
|
||||
|
||||
Eq ([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, $remote, $this.identifier()))
|
||||
}
|
||||
}
|
||||
|
||||
[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
|
||||
[string]$eqId
|
||||
|
||||
EqChannel ([int]$index, [Object]$remote, [string]$eqId) : base ($index, $remote) {
|
||||
$this.eqId = $eqId
|
||||
|
||||
$this.cell = @()
|
||||
$cellCount = $this.remote.kind.cells
|
||||
for ($c = 0; $c -lt $cellCount; $c++) {
|
||||
$this.cell.Add([EqCell]::new($c, $remote, $this.identifier()))
|
||||
}
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return '{0}.Channel[{1}]' -f $this.eqId, $this.index
|
||||
}
|
||||
}
|
||||
|
||||
class EqCell : IRemote {
|
||||
[string]$channelId
|
||||
|
||||
EqCell ([int]$index, [Object]$remote, [string]$channelId) : base ($index, $remote) {
|
||||
$this.channelId = $channelId
|
||||
|
||||
AddBoolMembers -PARAMS @('on')
|
||||
AddIntMembers -PARAMS @('type')
|
||||
AddFloatMembers -PARAMS @('f', 'gain', 'q')
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return '{0}.Cell[{1}]' -f $this.channelId, $this.index
|
||||
}
|
||||
}
|
||||
222
lib/io.ps1
Normal file
222
lib/io.ps1
Normal file
@@ -0,0 +1,222 @@
|
||||
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 {
|
||||
[string]$kindOfDevice
|
||||
[Hashtable]$drivers
|
||||
|
||||
IODevice ([int]$index, [Object]$remote, [string]$kindOfDevice) : base ($index, $remote) {
|
||||
$this.kindOfDevice = $kindOfDevice
|
||||
|
||||
AddStringMembers -WriteOnly -PARAMS @('wdm', 'ks', 'mme')
|
||||
AddStringMembers -ReadOnly -PARAMS @('name')
|
||||
AddIntMembers -ReadOnly -PARAMS @('sr')
|
||||
|
||||
$this.drivers = @{
|
||||
'1' = 'mme'
|
||||
'4' = 'wdm'
|
||||
'8' = 'ks'
|
||||
'256' = 'asio'
|
||||
}
|
||||
}
|
||||
|
||||
[int] EnumCount () {
|
||||
throw [System.NotImplementedException]::new("$($this.GetType().Name) must override EnumCount()")
|
||||
}
|
||||
|
||||
[PSObject] EnumDevice ([int]$eIndex) {
|
||||
throw [System.NotImplementedException]::new("$($this.GetType().Name) must override EnumDevice()")
|
||||
}
|
||||
|
||||
[PSObject] Get () {
|
||||
$device = [PSCustomObject]@{
|
||||
Driver = $this.driver
|
||||
Name = $this.name
|
||||
HardwareId = ''
|
||||
IsOutput = $this.kindOfDevice -eq 'Output'
|
||||
}
|
||||
if (-not [string]::IsNullOrEmpty($device.Name)) {
|
||||
for ($i = 0; $i -lt $this.EnumCount(); $i++) {
|
||||
$eDevice = $this.EnumDevice($i)
|
||||
if ($eDevice.Name -eq $device.Name -and $eDevice.Driver -eq $device.Driver) {
|
||||
$device = $eDevice
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return $device
|
||||
}
|
||||
|
||||
[void] Set ([PSObject]$device) {
|
||||
$required = 'IsOutput', 'Driver', 'Name'
|
||||
$missing = $required | Where-Object { $null -eq $device.PSObject.Properties[$_] }
|
||||
|
||||
if ($missing) {
|
||||
throw [System.ArgumentException]::new(("Invalid device object. Missing member(s): {0}" -f ($missing -join ', ')), 'device')
|
||||
}
|
||||
|
||||
$expectsOutput = ($this.kindOfDevice -eq 'Output')
|
||||
if ([bool]$device.IsOutput -ne $expectsOutput) {
|
||||
throw [System.ArgumentException]::new(("Device direction mismatch. Expected IsOutput={0}." -f $expectsOutput), 'device')
|
||||
}
|
||||
|
||||
$d = $device.Driver
|
||||
$n = $device.Name
|
||||
|
||||
if (-not ($d -is [string])) {
|
||||
throw [System.ArgumentException]::new('Invalid device object. Driver must be a string.', 'device')
|
||||
}
|
||||
if (-not ($n -is [string])) {
|
||||
throw [System.ArgumentException]::new('Invalid device object. Name must be a string.', 'device')
|
||||
}
|
||||
|
||||
if ($d -eq '' -and $n -eq '') { $this.Clear(); return }
|
||||
if ($d -notin $this.drivers.Values) {
|
||||
throw [System.ArgumentOutOfRangeException]::new('device.Driver', $d, 'Invalid device driver provided to Set method.')
|
||||
}
|
||||
|
||||
$this.Setter($d, $n)
|
||||
}
|
||||
|
||||
[void] Clear () {
|
||||
$this.Setter('mme', '')
|
||||
}
|
||||
|
||||
hidden $_driver = $($this | Add-Member ScriptProperty 'driver' `
|
||||
{
|
||||
if ([string]::IsNullOrEmpty($this.name)) { return '' }
|
||||
|
||||
$type = $null
|
||||
try {
|
||||
$tmp = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "vmrtmp-$(New-Guid).xml")
|
||||
$this.remote.Setter('Command.Save', $tmp)
|
||||
|
||||
$timeout = New-TimeSpan -Seconds 2
|
||||
$sw = [Diagnostics.Stopwatch]::StartNew()
|
||||
$line = $null
|
||||
do {
|
||||
if (Test-Path $tmp) {
|
||||
try {
|
||||
$line = Get-Content $tmp | Select-String -Pattern "<$($this.kindOfDevice)Dev index='$($this.index + 1)'" -List
|
||||
if ($line) { break }
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
Start-Sleep -Milliseconds 20
|
||||
} while ($sw.elapsed -lt $timeout)
|
||||
if ($line -and $line.ToString() -match "type='(?<type>\d+)'") {
|
||||
$type = $matches['type']
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (Test-Path $tmp) {
|
||||
Remove-Item $tmp -Force
|
||||
}
|
||||
}
|
||||
|
||||
if ($type -notin $this.drivers.Keys) { return 'unknown' }
|
||||
return $this.drivers[$type]
|
||||
} `
|
||||
{
|
||||
Write-Warning ("ERROR: $($this.identifier()).driver is read only")
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -9,9 +9,10 @@ $KindMap = @{
|
||||
'asio_out' = 8
|
||||
'composite' = 0
|
||||
'insert' = 0
|
||||
'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1 }
|
||||
'vban' = @{ 'in' = 4; 'out' = 4; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||
'eq_ch' = @{ 'strip' = 0; 'bus' = 0 }
|
||||
'cells' = 0
|
||||
'gainlayer' = 0
|
||||
};
|
||||
'banana' = @{
|
||||
'name' = 'banana'
|
||||
@@ -23,9 +24,10 @@ $KindMap = @{
|
||||
'asio_out' = 8
|
||||
'composite' = 8
|
||||
'insert' = 22
|
||||
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 }
|
||||
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||
'eq_ch' = @{ 'strip' = 0; 'bus' = 8 }
|
||||
'cells' = 6
|
||||
'gainlayer' = 0
|
||||
};
|
||||
'potato' = @{
|
||||
'name' = 'potato'
|
||||
@@ -37,9 +39,10 @@ $KindMap = @{
|
||||
'asio_out' = 8
|
||||
'composite' = 8
|
||||
'insert' = 34
|
||||
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1 }
|
||||
'vban' = @{ 'in' = 8; 'out' = 8; 'midi' = 1; 'text' = 1; 'video' = 1 }
|
||||
'eq_ch' = @{ 'strip' = 2; 'bus' = 8 }
|
||||
'cells' = 6
|
||||
'gainlayer' = 8
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
67
lib/meta.ps1
67
lib/meta.ps1
@@ -1,65 +1,57 @@
|
||||
function AddBoolMembers () {
|
||||
param(
|
||||
[String[]]$PARAMS
|
||||
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||
)
|
||||
[hashtable]$Signatures = @{}
|
||||
foreach ($param in $PARAMS) {
|
||||
# Define getter
|
||||
$Signatures['Getter'] = "[bool]`$this.Getter('{0}')" -f $param
|
||||
# Define setter
|
||||
$Signatures['Setter'] = "param ( [bool]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||
-f $param
|
||||
|
||||
Addmember
|
||||
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||
}
|
||||
}
|
||||
|
||||
function AddFloatMembers () {
|
||||
param(
|
||||
[String[]]$PARAMS,
|
||||
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly,
|
||||
[int]$decimals = 2
|
||||
)
|
||||
[hashtable]$Signatures = @{}
|
||||
foreach ($param in $PARAMS) {
|
||||
# Define getter
|
||||
$Signatures['Getter'] = "[math]::Round(`$this.Getter('{0}'), {1})" -f $param, $decimals
|
||||
# Define setter
|
||||
$Signatures['Setter'] = "param ( [Single]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||
-f $param
|
||||
|
||||
Addmember
|
||||
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||
}
|
||||
}
|
||||
|
||||
function AddIntMembers () {
|
||||
param(
|
||||
[String[]]$PARAMS
|
||||
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||
)
|
||||
[hashtable]$Signatures = @{}
|
||||
foreach ($param in $PARAMS) {
|
||||
# Define getter
|
||||
$Signatures['Getter'] = "[Int]`$this.Getter('{0}')" -f $param
|
||||
# Define setter
|
||||
$Signatures['Setter'] = "param ( [Int]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||
-f $param
|
||||
|
||||
Addmember
|
||||
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||
}
|
||||
}
|
||||
|
||||
function AddStringMembers () {
|
||||
param(
|
||||
[String[]]$PARAMS
|
||||
[String[]]$PARAMS, [Switch]$readOnly, [Switch]$writeOnly
|
||||
)
|
||||
[hashtable]$Signatures = @{}
|
||||
foreach ($param in $PARAMS) {
|
||||
# Define getter
|
||||
$Signatures['Getter'] = "[String]`$this.Getter_String('{0}')" -f $param
|
||||
# Define setter
|
||||
$Signatures['Setter'] = "param ( [String]`$arg )`n`$this.Setter('{0}', `$arg)" `
|
||||
-f $param
|
||||
|
||||
Addmember
|
||||
Addmember -ReadOnly:$readOnly -WriteOnly:$writeOnly
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +66,16 @@ function AddActionMembers () {
|
||||
}
|
||||
}
|
||||
|
||||
function AddAliasMembers () {
|
||||
param(
|
||||
[hashtable]$MAP
|
||||
)
|
||||
foreach ($alias in $MAP.Keys) {
|
||||
$this | Add-Member -MemberType AliasProperty -Name $alias `
|
||||
-Value $MAP[$alias] -Force
|
||||
}
|
||||
}
|
||||
|
||||
function AddChannelMembers () {
|
||||
$num_A = $this.remote.kind.p_out
|
||||
$num_B = $this.remote.kind.v_out
|
||||
@@ -86,22 +88,25 @@ function AddChannelMembers () {
|
||||
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 {
|
||||
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 = @{
|
||||
Name = $param
|
||||
MemberType = 'ScriptProperty'
|
||||
|
||||
@@ -25,6 +25,7 @@ class Recorder : IRemote {
|
||||
AddActionMembers -PARAMS @('replay', 'ff', 'rew')
|
||||
AddFloatMembers -PARAMS @('gain')
|
||||
AddIntMembers -PARAMS @('prerectime')
|
||||
AddStringMembers -PARAMS @('prefix') -WriteOnly
|
||||
|
||||
AddChannelMembers
|
||||
}
|
||||
@@ -117,16 +118,6 @@ class Recorder : IRemote {
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_prefix = $($this | Add-Member ScriptProperty 'prefix' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).prefix is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
$this._prefix = $this.Setter('prefix', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_filetype = $($this | Add-Member ScriptProperty 'filetype' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).filetype is write only")
|
||||
|
||||
159
lib/strip.ps1
159
lib/strip.ps1
@@ -1,32 +1,27 @@
|
||||
class Strip : IRemote {
|
||||
class Strip : IOControl {
|
||||
[System.Collections.ArrayList]$gainlayer
|
||||
[Object]$levels
|
||||
|
||||
Strip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('mono', 'solo', 'mute')
|
||||
AddIntMembers -PARAMS @('limit')
|
||||
AddFloatMembers -PARAMS @('gain', 'pan_x', 'pan_y')
|
||||
AddStringMembers -PARAMS @('label')
|
||||
AddBoolMembers -PARAMS @('solo')
|
||||
AddFloatMembers -PARAMS @('limit', 'pan_x', 'pan_y')
|
||||
|
||||
AddChannelMembers
|
||||
AddGainlayerMembers
|
||||
|
||||
$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] identifier () {
|
||||
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 : IRemote {
|
||||
class StripLevels : IOLevels {
|
||||
[int]$init
|
||||
[int]$offset
|
||||
|
||||
@@ -42,23 +37,6 @@ class StripLevels : IRemote {
|
||||
}
|
||||
}
|
||||
|
||||
[float] Convert([float]$val) {
|
||||
if ($val -gt 0) {
|
||||
return [math]::Round(20 * [math]::Log10($val), 1)
|
||||
}
|
||||
else {
|
||||
return -200.0
|
||||
}
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] Getter([int]$mode) {
|
||||
[System.Collections.ArrayList]$vals = @()
|
||||
$this.init..$($this.init + $this.offset - 1) | ForEach-Object {
|
||||
$vals.Add($this.Convert($(Get_Level -MODE $mode -INDEX $_)))
|
||||
}
|
||||
return $vals
|
||||
}
|
||||
|
||||
[System.Collections.ArrayList] PreFader() {
|
||||
return $this.Getter(0)
|
||||
}
|
||||
@@ -78,21 +56,41 @@ class PhysicalStrip : Strip {
|
||||
[Object]$denoiser
|
||||
[Object]$eq
|
||||
[Object]$device
|
||||
[Object]$audibility
|
||||
[Object]$pitch
|
||||
|
||||
PhysicalStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddFloatMembers -PARAMS @('color_x', 'color_y', 'fx_x', 'fx_y')
|
||||
AddFloatMembers -PARAMS @('reverb', 'delay', 'fx1', 'fx2')
|
||||
AddBoolMembers -PARAMS @('postreverb', 'postdelay', 'postfx1', 'postfx2')
|
||||
AddBoolMembers -PARAMS @('mono', 'vaio')
|
||||
|
||||
$this.comp = [StripComp]::new($index, $remote)
|
||||
$this.gate = [StripGate]::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.device = [StripDevice]::new($index, $remote)
|
||||
}
|
||||
}
|
||||
|
||||
class StripComp : IRemote {
|
||||
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) {
|
||||
AddFloatMembers -PARAMS @('gainin', 'ratio', 'threshold', 'attack', 'release', 'knee', 'gainout')
|
||||
AddBoolMembers -PARAMS @('makeup')
|
||||
@@ -101,19 +99,9 @@ class StripComp : IRemote {
|
||||
[string] identifier () {
|
||||
return 'Strip[' + $this.index + '].Comp'
|
||||
}
|
||||
|
||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
||||
{
|
||||
$this.Getter_String('')
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
return $this.Setter('', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class StripGate : IRemote {
|
||||
class StripGate : StripKnob {
|
||||
StripGate ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddFloatMembers -PARAMS @('threshold', 'damping', 'bpsidechain', 'attack', 'hold', 'release')
|
||||
}
|
||||
@@ -121,38 +109,43 @@ class StripGate : IRemote {
|
||||
[string] identifier () {
|
||||
return 'Strip[' + $this.index + '].Gate'
|
||||
}
|
||||
|
||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
||||
{
|
||||
$this.Getter_String('')
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
return $this.Setter('', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class StripDenoiser : IRemote {
|
||||
class StripDenoiser : StripKnob {
|
||||
StripDenoiser ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddFloatMembers -PARAMS @('threshold')
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return 'Strip[' + $this.index + '].Denoiser'
|
||||
}
|
||||
|
||||
hidden $_knob = $($this | Add-Member ScriptProperty 'knob' `
|
||||
{
|
||||
$this.Getter_String('')
|
||||
} `
|
||||
{
|
||||
param($arg)
|
||||
return $this.Setter('', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class StripEq : Eq {
|
||||
class StripPitch : IRemote {
|
||||
StripPitch ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('on')
|
||||
AddFloatMembers -PARAMS @('drywet', 'pitchvalue', 'loformant', 'medformant', 'hiformant')
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return 'Strip[' + $this.index + '].Pitch'
|
||||
}
|
||||
|
||||
[void] RecallPreset ([int]$presetIndex) {
|
||||
$this.Setter('RecallPreset', $presetIndex)
|
||||
}
|
||||
}
|
||||
|
||||
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') {
|
||||
}
|
||||
|
||||
@@ -161,27 +154,55 @@ class StripEq : Eq {
|
||||
}
|
||||
}
|
||||
|
||||
class StripDevice : Device {
|
||||
StripDevice ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
class StripDevice : IODevice {
|
||||
StripDevice ([int]$index, [Object]$remote) : base ($index, $remote, 'Input') {
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return 'Strip[' + $this.index + '].Device'
|
||||
}
|
||||
|
||||
[int] EnumCount () {
|
||||
return $this.remote.GetInputCount()
|
||||
}
|
||||
|
||||
[PSObject] EnumDevice ([int]$eIndex) {
|
||||
return $this.remote.GetInputDevice($eIndex)
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualStrip : Strip {
|
||||
VirtualStrip ([int]$index, [Object]$remote) : base ($index, $remote) {
|
||||
AddBoolMembers -PARAMS @('mc')
|
||||
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) {
|
||||
$this.Setter('AppGain', "(`"$appname`", $gain)")
|
||||
}
|
||||
|
||||
[void] AppGain ([int]$appindex, [single]$gain) {
|
||||
$this.Setter("App[$appindex].Gain", $gain)
|
||||
}
|
||||
|
||||
[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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
287
lib/vban.ps1
287
lib/vban.ps1
@@ -3,18 +3,14 @@ class Vban : IRemote {
|
||||
|
||||
Vban ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote) {
|
||||
$this.direction = $direction
|
||||
|
||||
AddBoolMembers -PARAMS @('on')
|
||||
AddStringMembers -PARAMS @('name', 'ip')
|
||||
}
|
||||
|
||||
[string] identifier () {
|
||||
return 'vban.' + $this.direction + 'stream[' + $this.index + ']'
|
||||
}
|
||||
}
|
||||
|
||||
class VbanAudio : Vban {
|
||||
VbanAudio ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
AddBoolMembers -PARAMS @('on')
|
||||
AddStringMembers -PARAMS @('name', 'ip')
|
||||
}
|
||||
|
||||
hidden $_port = $($this | Add-Member ScriptProperty 'port' `
|
||||
{
|
||||
@@ -30,43 +26,33 @@ class VbanAudio : Vban {
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
||||
{
|
||||
[int]$this.Getter('sr')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||
if ($opts.Contains($arg)) {
|
||||
$this._sr = $this.Setter('sr', $arg)
|
||||
}
|
||||
else {
|
||||
Write-Warning ('Expected one of', $opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
class VbanAudio : Vban {
|
||||
VbanAudio ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
AddIntMembers -PARAMS @('quality', 'route')
|
||||
}
|
||||
}
|
||||
|
||||
hidden $_channel = $($this | Add-Member ScriptProperty 'channel' `
|
||||
{
|
||||
[int]$this.Getter('channel')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
if ($arg -ge 1 -and $arg -le 8) {
|
||||
$this._channel = $this.Setter('channel', $arg)
|
||||
}
|
||||
else {
|
||||
Write-Warning ('Expected value from 1 to 8')
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
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' `
|
||||
{
|
||||
@@ -74,125 +60,9 @@ class VbanAudio : Vban {
|
||||
return $val
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
if ($this.direction -eq 'in') { Write-Warning ('Error, read only value') }
|
||||
else {
|
||||
if (@(16, 24).Contains($arg)) {
|
||||
$val = if ($arg -eq 16) { 1 } else { 2 }
|
||||
$this._bit = $this.Setter('bit', $val)
|
||||
}
|
||||
else {
|
||||
Write-Warning ('Expected value 16 or 24')
|
||||
}
|
||||
}
|
||||
Write-Warning ("ERROR: $($this.identifier()).bit is read only")
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_quality = $($this | Add-Member ScriptProperty 'quality' `
|
||||
{
|
||||
[int]$this.Getter('quality')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
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' `
|
||||
{
|
||||
[int]$this.Getter('route')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
$rt = $this.remote.kind['p_' + $this.direction] + $this.remote.kind['v_' + $this.direction] - 1
|
||||
if ($arg -ge 0 -and $arg -le $rt) {
|
||||
$this._route = $this.Setter('route', $arg)
|
||||
}
|
||||
else {
|
||||
Write-Warning ("Expected value from 0 to $rt")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class VbanMidi : Vban {
|
||||
VbanMidi ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
}
|
||||
|
||||
hidden $_on = $($this | Add-Member ScriptProperty 'on' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).on is write only")
|
||||
} `
|
||||
{
|
||||
param([bool]$arg)
|
||||
$this._on = $this.Setter('on', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).name is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
$this._name = $this.Setter('name', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_ip = $($this | Add-Member ScriptProperty 'ip' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).ip is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
$this._ip = $this.Setter('ip', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class VbanText : Vban {
|
||||
VbanText ([int]$index, [Object]$remote, [string]$direction) : base ($index, $remote, $direction) {
|
||||
}
|
||||
|
||||
hidden $_on = $($this | Add-Member ScriptProperty 'on' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).on is write only")
|
||||
} `
|
||||
{
|
||||
param([bool]$arg)
|
||||
$this._on = $this.Setter('on', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_name = $($this | Add-Member ScriptProperty 'name' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).name is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
$this._name = $this.Setter('name', $arg)
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_ip = $($this | Add-Member ScriptProperty 'ip' `
|
||||
{
|
||||
return Write-Warning ("ERROR: $($this.identifier()).ip is write only")
|
||||
} `
|
||||
{
|
||||
param([string]$arg)
|
||||
$this._ip = $this.Setter('ip', $arg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class VbanInAudio : VbanAudio {
|
||||
VbanInAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'in') {
|
||||
}
|
||||
}
|
||||
|
||||
class VbanInMidi : VbanMidi {
|
||||
@@ -207,12 +77,104 @@ class VbanInText : VbanText {
|
||||
|
||||
class VbanOutAudio : VbanAudio {
|
||||
VbanOutAudio ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||
AddIntMembers -PARAMS @('channel')
|
||||
}
|
||||
|
||||
hidden $_sr = $($this | Add-Member ScriptProperty 'sr' `
|
||||
{
|
||||
[int]$this.Getter('sr')
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
$opts = @(11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||
if ($opts.Contains($arg)) {
|
||||
$this._sr = $this.Setter('sr', $arg)
|
||||
}
|
||||
else {
|
||||
Write-Warning ('Expected one of', $opts)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
hidden $_bit = $($this | Add-Member ScriptProperty 'bit' `
|
||||
{
|
||||
$val = if ($this.Getter('bit') -eq 1) { 16 } else { 24 }
|
||||
return $val
|
||||
} `
|
||||
{
|
||||
param([int]$arg)
|
||||
if (@(16, 24).Contains($arg)) {
|
||||
$val = if ($arg -eq 16) { 1 } else { 2 }
|
||||
$this._bit = $this.Setter('bit', $val)
|
||||
}
|
||||
else {
|
||||
Write-Warning ('Expected value 16 or 24')
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
class VbanOutMidi : VbanMidi {
|
||||
VbanOutMidi ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||
}
|
||||
|
||||
hidden $_route = $($this | Add-Member ScriptProperty '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([string]$arg)
|
||||
[int]$val = 0
|
||||
switch ($arg) {
|
||||
'none' { $val = 0 }
|
||||
'midi_in' { $val = 1 }
|
||||
'aux_in' { $val = 2 }
|
||||
'vban_in' { $val = 4 }
|
||||
'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 {
|
||||
VbanOutVideo ([int]$index, [Object]$remote) : base ($index, $remote, 'out') {
|
||||
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)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function Make_Vban ([Object]$remote) {
|
||||
@@ -220,7 +182,7 @@ function Make_Vban ([Object]$remote) {
|
||||
[System.Collections.ArrayList]$outstream = @()
|
||||
|
||||
$totalInstreams = $remote.kind.vban.in + $remote.kind.vban.midi + $remote.kind.vban.text
|
||||
$totalOutstreams = $remote.kind.vban.out + $remote.kind.vban.midi
|
||||
$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) {
|
||||
@@ -237,9 +199,12 @@ function Make_Vban ([Object]$remote) {
|
||||
if ($i -lt $remote.kind.vban.out) {
|
||||
[void]$outstream.Add([VbanOutAudio]::new($i, $remote))
|
||||
}
|
||||
else {
|
||||
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]@{
|
||||
|
||||
@@ -30,6 +30,23 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
Context 'Strip, physical only' -ForEach @(
|
||||
@{ Index = $phys_in }
|
||||
) {
|
||||
It "Should set Strip[$index].Mono" {
|
||||
$vmr.strip[$index].mono = $value
|
||||
$vmr.strip[$index].mono | Should -Be $expected
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].VAIO" {
|
||||
$vmr.strip[$index].vaio = $value
|
||||
$vmr.strip[$index].vaio | Should -Be $expected
|
||||
}
|
||||
|
||||
Context 'Pitch' -Skip:$ifNotPotato {
|
||||
It "Should set Strip[$index].Pitch.On" {
|
||||
$vmr.strip[$index].pitch.on = $value
|
||||
$vmr.strip[$index].pitch.on | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Eq' -Skip:$ifNotPotato -ForEach @(
|
||||
@{ Eq = $vmr.strip[$index].eq }
|
||||
) {
|
||||
@@ -50,6 +67,15 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Strip, first virtual' -ForEach @(
|
||||
@{ Index = $phys_in + 1 }
|
||||
) {
|
||||
It "Should set Strip[$index].MC via alias 'Mono'" {
|
||||
$vmr.strip[$index].mono = $value
|
||||
$vmr.strip[$index].mc | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Bus, one physical one virtual' -ForEach @(
|
||||
@{ Index = $phys_out }, @{ Index = $virt_out }
|
||||
) {
|
||||
@@ -124,10 +150,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.vban.enable | Should -Be $expected
|
||||
}
|
||||
|
||||
Context 'Instream' -ForEach @(
|
||||
Context 'Instream, audio, midi, text' -ForEach @(
|
||||
@{ Index = $vban_inA }
|
||||
# @{ Index = $vban_inM }
|
||||
# @{ Index = $vban_inT }
|
||||
@{ Index = $vban_inM }
|
||||
@{ Index = $vban_inT }
|
||||
) {
|
||||
It "Should set vban.instream[$index].on" {
|
||||
$vmr.vban.instream[$index].on = $value
|
||||
@@ -135,15 +161,25 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream' -ForEach @(
|
||||
Context 'Outstream, audio, midi, video' -ForEach @(
|
||||
@{ Index = $vban_outA }
|
||||
# @{ Index = $vban_outM }
|
||||
@{ Index = $vban_outM }
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].on" {
|
||||
$vmr.vban.outstream[$index].on = $value
|
||||
$vmr.vban.outstream[$index].on | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream, video only' -ForEach @(
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].vcursor" {
|
||||
$vmr.vban.outstream[$index].vcursor = $value
|
||||
$vmr.vban.outstream[$index].vcursor | Should -Be $expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Recorder' -Skip:$ifBasic {
|
||||
@@ -246,7 +282,7 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
|
||||
Describe 'Float Tests' -Tag 'float' -ForEach @(
|
||||
@{ Gain = -24.63; Knob = 5.27; Slide = -7.51; Xy10 = 0.83; Xy05 = -0.42; MsHz = 196.57 }
|
||||
@{ Gain = -12.48; Knob = 8.91; Slide = 3.14; Xy10 = 0.27; Xy05 = 0.69; MsHz = 142.13 }
|
||||
@{ Gain = -12.48; Knob = 8.91; Slide = 3.14; Xy10 = 0.27; Xy05 = 0.29; MsHz = 142.13 }
|
||||
) {
|
||||
Context 'Strip, one physical one virtual' -ForEach @(
|
||||
@{ Index = $phys_in }, @{ Index = $virt_in }
|
||||
@@ -255,11 +291,30 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.strip[$index].gain = $gain
|
||||
$vmr.strip[$index].gain | Should -Be $gain
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Limit" -Skip:$ifBasic {
|
||||
$vmr.strip[$index].limit = $gain
|
||||
$vmr.strip[$index].limit | Should -Be $gain
|
||||
}
|
||||
|
||||
Context 'Gainlayers' -Skip:$ifNotPotato -ForEach @(
|
||||
@{ Layer = $phys_out }, @{ Layer = $virt_out }
|
||||
) {
|
||||
It "Should set Strip[$index].Gainlayer[$layer]" {
|
||||
$vmr.strip[$index].gainlayer[$layer].set($gain)
|
||||
$vmr.strip[$index].gainlayer[$layer].get() | Should -Be $gain
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Strip, physical only' -ForEach @(
|
||||
@{ Index = $phys_in }
|
||||
) {
|
||||
It "Should set Strip[$index].Pan_Y" {
|
||||
$vmr.strip[$index].pan_y = $xy10
|
||||
$vmr.strip[$index].pan_y | Should -Be $xy10
|
||||
}
|
||||
|
||||
Context 'Comp, Gate' -Skip:$ifBasic {
|
||||
It "Should set Strip[$index].Comp" {
|
||||
$vmr.strip[$index].comp.knob = $knob
|
||||
@@ -301,6 +356,45 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.strip[$index].denoiser.knob = $knob
|
||||
$vmr.strip[$index].denoiser.knob | Should -Be $knob
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Denoiser.Threshold" {
|
||||
$vmr.strip[$index].denoiser.threshold = $knob
|
||||
$vmr.strip[$index].denoiser.threshold | Should -Be $knob
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Pitch' -Skip:$ifNotPotato {
|
||||
It "Should set Strip[$index].Pitch.drywet" {
|
||||
$vmr.strip[$index].pitch.drywet = $slide
|
||||
$vmr.strip[$index].pitch.drywet | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Pitch.pitchvalue" {
|
||||
$vmr.strip[$index].pitch.pitchvalue = $slide
|
||||
$vmr.strip[$index].pitch.pitchvalue | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Pitch.loformant" {
|
||||
$vmr.strip[$index].pitch.loformant = $slide
|
||||
$vmr.strip[$index].pitch.loformant | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Pitch.medformant" {
|
||||
$vmr.strip[$index].pitch.medformant = $slide
|
||||
$vmr.strip[$index].pitch.medformant | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Pitch.hiformant" {
|
||||
$vmr.strip[$index].pitch.hiformant = $slide
|
||||
$vmr.strip[$index].pitch.hiformant | Should -Be $slide
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Audibility' -Skip:$ifNotBasic {
|
||||
It "Should set Strip[$index].Audibility" {
|
||||
$vmr.strip[$index].audibility.knob = $knob
|
||||
$vmr.strip[$index].audibility.knob | Should -Be $knob
|
||||
}
|
||||
}
|
||||
|
||||
Context 'EQ' -Skip:$ifNotPotato -ForEach @(
|
||||
@@ -323,6 +417,53 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Strip, virtual only' -ForEach @(
|
||||
@{ Index = $virt_in }
|
||||
) {
|
||||
It "Should set Strip[$index].Pan_Y" {
|
||||
$vmr.strip[$index].pan_y = $xy05
|
||||
$vmr.strip[$index].pan_y | Should -Be $xy05
|
||||
}
|
||||
|
||||
Context 'EQ' {
|
||||
BeforeEach {
|
||||
$vmr.strip[$index].eqgain1 = 0
|
||||
$vmr.strip[$index].eqgain2 = 0
|
||||
$vmr.strip[$index].eqgain3 = 0
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain1 via alias 'bass'" {
|
||||
$vmr.strip[$index].bass = $slide
|
||||
$vmr.strip[$index].eqgain1 | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain1 via alias 'low'" {
|
||||
$vmr.strip[$index].low = $slide
|
||||
$vmr.strip[$index].eqgain1 | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain2 via alias 'mid'" {
|
||||
$vmr.strip[$index].mid = $slide
|
||||
$vmr.strip[$index].eqgain2 | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain2 via alias 'med'" {
|
||||
$vmr.strip[$index].med = $slide
|
||||
$vmr.strip[$index].eqgain2 | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain3 via alias 'treble'" {
|
||||
$vmr.strip[$index].treble = $slide
|
||||
$vmr.strip[$index].eqgain3 | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].EQGain3 via alias 'high'" {
|
||||
$vmr.strip[$index].high = $slide
|
||||
$vmr.strip[$index].eqgain3 | Should -Be $slide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Bus, one physical one virtual' -ForEach @(
|
||||
@{ Index = $phys_out }, @{ Index = $virt_out }
|
||||
) {
|
||||
@@ -334,19 +475,33 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
Context 'EQ' -Skip:$ifBasic -ForEach @(
|
||||
@{ Eq = $vmr.bus[$index].eq }
|
||||
) {
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].F" {
|
||||
$eq.channel[$bus_ch].cell[$cells].f = $msHz
|
||||
$eq.channel[$bus_ch].cell[$cells].f | Should -Be $msHz
|
||||
}
|
||||
Context "Channel[$bus_ch]" {
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Trim" {
|
||||
$eq.channel[$bus_ch].trim = $slide
|
||||
$eq.channel[$bus_ch].trim | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Gain" {
|
||||
$eq.channel[$bus_ch].cell[$cells].gain = $slide
|
||||
$eq.channel[$bus_ch].cell[$cells].gain | Should -Be $slide
|
||||
}
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Delay" {
|
||||
$eq.channel[$bus_ch].delay = $msHz
|
||||
$eq.channel[$bus_ch].delay | Should -Be $msHz
|
||||
}
|
||||
|
||||
Context "Cell[$cells]" {
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].F" {
|
||||
$eq.channel[$bus_ch].cell[$cells].f = $msHz
|
||||
$eq.channel[$bus_ch].cell[$cells].f | Should -Be $msHz
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Q" {
|
||||
$eq.channel[$bus_ch].cell[$cells].q = $knob
|
||||
$eq.channel[$bus_ch].cell[$cells].q | Should -Be $knob
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Gain" {
|
||||
$eq.channel[$bus_ch].cell[$cells].gain = $slide
|
||||
$eq.channel[$bus_ch].cell[$cells].gain | Should -Be $slide
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].EQ.Channel[$bus_ch].Cell[$cells].Q" {
|
||||
$eq.channel[$bus_ch].cell[$cells].q = $knob
|
||||
$eq.channel[$bus_ch].cell[$cells].q | Should -Be $knob
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,18 +517,6 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
|
||||
Describe 'Int Tests' -Tag 'int' {
|
||||
Context 'Strip, one physical, one virtual' -ForEach @(
|
||||
@{ Index = $phys_in }, @{ Index = $virt_in }
|
||||
) {
|
||||
It "Should set and get Strip[$index].Limit" -Skip:$ifBasic -ForEach @(
|
||||
@{ Value = 3; Expected = 3 }
|
||||
@{ Value = -6; Expected = -6 }
|
||||
) {
|
||||
$vmr.strip[$index].limit = $value
|
||||
$vmr.strip[$index].limit | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Strip, physical only' -ForEach @(
|
||||
@{ Index = $phys_in }
|
||||
) {
|
||||
@@ -395,6 +538,19 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Strip, second virtual' -Skip:$ifBasic -ForEach @(
|
||||
@{ Index = $phys_in + 2 }
|
||||
) {
|
||||
It "Should set Strip[$index].K via alias 'Karaoke'" -ForEach @(
|
||||
@{ Value = 0; Expected = 0 }
|
||||
@{ Value = 2; Expected = 2 }
|
||||
@{ Value = 4; Expected = 4 }
|
||||
) {
|
||||
$vmr.strip[$index].karaoke = $value
|
||||
$vmr.strip[$index].k | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Bus, one physical one virtual' -ForEach @(
|
||||
@{ Index = $phys_out }, @{ Index = $virt_out }
|
||||
) {
|
||||
@@ -450,8 +606,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.vban.port | Should -Be $expected
|
||||
}
|
||||
|
||||
Context 'Instream' -ForEach @(
|
||||
Context 'Instream, audio, midi, text' -ForEach @(
|
||||
@{ Index = $vban_inA }
|
||||
@{ Index = $vban_inM }
|
||||
@{ Index = $vban_inT }
|
||||
) {
|
||||
It "Should set vban.instream[$index].port" -ForEach @(
|
||||
@{ Value = 1024; Expected = 1024 }
|
||||
@@ -462,16 +620,21 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
Start-Sleep -Milliseconds 2000
|
||||
$vmr.vban.instream[$index].port | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
It "Should set vban.instream[$index].sr" {
|
||||
Context 'Instream, audio only' -ForEach @(
|
||||
@{ Index = $vban_inA }
|
||||
) {
|
||||
|
||||
It "Should get vban.instream[$index].sr" {
|
||||
$vmr.vban.instream[$index].sr | Should -BeOfType [int]
|
||||
}
|
||||
|
||||
It "Should set vban.instream[$index].channel" {
|
||||
It "Should get vban.instream[$index].channel" {
|
||||
$vmr.vban.instream[$index].channel | Should -BeOfType [int]
|
||||
}
|
||||
|
||||
It "Should set vban.instream[$index].bit" {
|
||||
It "Should get vban.instream[$index].bit" {
|
||||
$vmr.vban.instream[$index].bit | Should -BeOfType [int]
|
||||
}
|
||||
|
||||
@@ -493,8 +656,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream' -ForEach @(
|
||||
Context 'Outstream, audio, midi, video' -ForEach @(
|
||||
@{ Index = $vban_outA }
|
||||
@{ Index = $vban_outM }
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].port" -ForEach @(
|
||||
@{ Value = 1024; Expected = 1024 }
|
||||
@@ -505,6 +670,11 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
Start-Sleep -Milliseconds 2000
|
||||
$vmr.vban.outstream[$index].port | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream, audio only' -ForEach @(
|
||||
@{ Index = $vban_outA }
|
||||
) {
|
||||
|
||||
It "Should set vban.outstream[$index].sr" -ForEach @(
|
||||
@{ Value = 44100; Expected = 44100 }
|
||||
@@ -547,6 +717,34 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.vban.outstream[$index].route | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream, video only' -ForEach @(
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].vfps" -ForEach @(
|
||||
@{ Value = 6; Expected = 6 }
|
||||
@{ Value = 24; Expected = 24 }
|
||||
) {
|
||||
$vmr.vban.outstream[$index].vfps = $value
|
||||
$vmr.vban.outstream[$index].vfps | Should -Be $expected
|
||||
}
|
||||
|
||||
It "Should set vban.outstream[$index].vquality" -ForEach @(
|
||||
@{ Value = 80; Expected = 80 }
|
||||
@{ Value = 100; Expected = 100 }
|
||||
) {
|
||||
$vmr.vban.outstream[$index].vquality = $value
|
||||
$vmr.vban.outstream[$index].vquality | Should -Be $expected
|
||||
}
|
||||
|
||||
<# It "Should set vban.outstream[$index].route" -ForEach @(
|
||||
@{ Value = 1; Expected = 1 }
|
||||
@{ Value = 4; Expected = 4 }
|
||||
) {
|
||||
$vmr.vban.outstream[$index].route = $value
|
||||
$vmr.vban.outstream[$index].route | Should -Be $expected
|
||||
} #>
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Patch' {
|
||||
@@ -652,24 +850,47 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
@{ Index = $phys_in }
|
||||
) {
|
||||
Context 'Device' -ForEach @(
|
||||
@{ Value = 'testInput' }, @{ Value = '' }
|
||||
@{ Driver = 'mme'; Value = 'testMme'; Expected = 'mme' }
|
||||
@{ Driver = 'wdm'; Value = 'testWdm'; Expected = 'wdm' }
|
||||
@{ Driver = 'ks'; Value = 'testKs'; Expected = 'ks' }
|
||||
@{ Driver = 'mme'; Value = ''; Expected = '' }
|
||||
) {
|
||||
It "Should set Strip[$index].Device.wdm" {
|
||||
$vmr.strip[$index].device.wdm = $value
|
||||
BeforeEach {
|
||||
$vmr.strip[$index].device.Clear()
|
||||
Start-Sleep -Milliseconds 800
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Device.$($driver)" {
|
||||
$vmr.strip[$index].device.name | Should -Be ''
|
||||
$vmr.strip[$index].device.driver | Should -Be ''
|
||||
|
||||
$vmr.strip[$index].device.$($driver) = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.strip[$index].device.name | Should -Be $value
|
||||
$vmr.strip[$index].device.driver | Should -Be $expected
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Device.ks" {
|
||||
$vmr.strip[$index].device.ks = $value
|
||||
It "Should set Strip[$index].Device" -ForEach @(
|
||||
@{
|
||||
Clear = [PSCustomObject]@{ Driver = ''; Name = ''; HardwareId = ''; IsOutput = $false }
|
||||
Device = [PSCustomObject]@{ Driver = $expected; Name = $value; HardwareId = ''; IsOutput = $false }
|
||||
}
|
||||
) {
|
||||
$initial = $vmr.strip[$index].device.Get()
|
||||
|
||||
$initial.Driver | Should -Be $clear.Driver
|
||||
$initial.Name | Should -Be $clear.Name
|
||||
$initial.HardwareId | Should -Be $clear.HardwareId
|
||||
$initial.IsOutput | Should -Be $clear.IsOutput
|
||||
|
||||
$vmr.strip[$index].device.Set($device)
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.strip[$index].device.name | Should -Be $value
|
||||
}
|
||||
|
||||
It "Should set Strip[$index].Device.mme" {
|
||||
$vmr.strip[$index].device.mme = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.strip[$index].device.name | Should -Be $value
|
||||
$result = $vmr.strip[$index].device.Get()
|
||||
|
||||
$result.Driver | Should -Be $device.Driver
|
||||
$result.Name | Should -Be $device.Name
|
||||
$result.HardwareId | Should -Be $device.HardwareId
|
||||
$result.IsOutput | Should -Be $device.IsOutput
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,24 +1006,47 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
@{ Index = $phys_out }
|
||||
) {
|
||||
Context 'Device' -ForEach @(
|
||||
@{ Value = 'testOutput' }, @{ Value = '' }
|
||||
@{ Driver = 'mme'; Value = 'testMme'; Expected = 'mme' }
|
||||
@{ Driver = 'wdm'; Value = 'testWdm'; Expected = 'wdm' }
|
||||
@{ Driver = 'ks'; Value = 'testKs'; Expected = 'ks' }
|
||||
@{ Driver = 'mme'; Value = ''; Expected = '' }
|
||||
) {
|
||||
It "Should set Bus[$index].Device.wdm" {
|
||||
$vmr.bus[$index].device.wdm = $value
|
||||
BeforeEach {
|
||||
$vmr.bus[$index].device.Clear()
|
||||
Start-Sleep -Milliseconds 800
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.$($driver)" {
|
||||
$vmr.bus[$index].device.name | Should -Be ''
|
||||
$vmr.bus[$index].device.driver | Should -Be ''
|
||||
|
||||
$vmr.bus[$index].device.$($driver) = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
$vmr.bus[$index].device.driver | Should -Be $expected
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.ks" {
|
||||
$vmr.bus[$index].device.ks = $value
|
||||
It "Should set Bus[$index].Device" -ForEach @(
|
||||
@{
|
||||
Clear = [PSCustomObject]@{ Driver = ''; Name = ''; HardwareId = ''; IsOutput = $true }
|
||||
Device = [PSCustomObject]@{ Driver = $expected; Name = $value; HardwareId = ''; IsOutput = $true }
|
||||
}
|
||||
) {
|
||||
$initial = $vmr.bus[$index].device.Get()
|
||||
|
||||
$initial.Driver | Should -Be $clear.Driver
|
||||
$initial.Name | Should -Be $clear.Name
|
||||
$initial.HardwareId | Should -Be $clear.HardwareId
|
||||
$initial.IsOutput | Should -Be $clear.IsOutput
|
||||
|
||||
$vmr.bus[$index].device.Set($device)
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.mme" {
|
||||
$vmr.bus[$index].device.mme = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
$result = $vmr.bus[$index].device.Get()
|
||||
|
||||
$result.Driver | Should -Be $device.Driver
|
||||
$result.Name | Should -Be $device.Name
|
||||
$result.HardwareId | Should -Be $device.HardwareId
|
||||
$result.IsOutput | Should -Be $device.IsOutput
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -811,33 +1055,56 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
@{ Index = $virt_out }
|
||||
) {
|
||||
Context 'Device' -Skip:$ifNotBasic -ForEach @(
|
||||
@{ Value = 'testOutput' }, @{ Value = '' }
|
||||
@{ Driver = 'mme'; Value = 'testMme'; Expected = 'mme' }
|
||||
@{ Driver = 'wdm'; Value = 'testWdm'; Expected = 'wdm' }
|
||||
@{ Driver = 'ks'; Value = 'testKs'; Expected = 'ks' }
|
||||
@{ Driver = 'mme'; Value = ''; Expected = '' }
|
||||
) {
|
||||
It "Should set Bus[$index].Device.wdm" {
|
||||
$vmr.bus[$index].device.wdm = $value
|
||||
BeforeEach {
|
||||
$vmr.bus[$index].device.Clear()
|
||||
Start-Sleep -Milliseconds 800
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.$($driver)" {
|
||||
$vmr.bus[$index].device.name | Should -Be ''
|
||||
$vmr.bus[$index].device.driver | Should -Be ''
|
||||
|
||||
$vmr.bus[$index].device.$($driver) = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
$vmr.bus[$index].device.driver | Should -Be $expected
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.ks" {
|
||||
$vmr.bus[$index].device.ks = $value
|
||||
It "Should set Bus[$index].Device" -ForEach @(
|
||||
@{
|
||||
Clear = [PSCustomObject]@{ Driver = ''; Name = ''; HardwareId = ''; IsOutput = $true }
|
||||
Device = [PSCustomObject]@{ Driver = $expected; Name = $value; HardwareId = ''; IsOutput = $true }
|
||||
}
|
||||
) {
|
||||
$initial = $vmr.bus[$index].device.Get()
|
||||
|
||||
$initial.Driver | Should -Be $clear.Driver
|
||||
$initial.Name | Should -Be $clear.Name
|
||||
$initial.HardwareId | Should -Be $clear.HardwareId
|
||||
$initial.IsOutput | Should -Be $clear.IsOutput
|
||||
|
||||
$vmr.bus[$index].device.Set($device)
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
}
|
||||
|
||||
It "Should set Bus[$index].Device.mme" {
|
||||
$vmr.bus[$index].device.mme = $value
|
||||
Start-Sleep -Milliseconds 800
|
||||
$vmr.bus[$index].device.name | Should -Be $value
|
||||
$result = $vmr.bus[$index].device.Get()
|
||||
|
||||
$result.Driver | Should -Be $device.Driver
|
||||
$result.Name | Should -Be $device.Name
|
||||
$result.HardwareId | Should -Be $device.HardwareId
|
||||
$result.IsOutput | Should -Be $device.IsOutput
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe 'Vban' {
|
||||
Context 'Instream' -ForEach @(
|
||||
Context 'Instream, audio, midi, text' -ForEach @(
|
||||
@{ Index = $vban_inA }
|
||||
# @{ Index = $vban_inM }
|
||||
# @{ Index = $vban_inT }
|
||||
@{ Index = $vban_inM }
|
||||
@{ Index = $vban_inT }
|
||||
) {
|
||||
It "Should set vban.instream[$index].name" -ForEach @(
|
||||
@{ Value = 'TestIn0'; Expected = 'TestIn0' }
|
||||
@@ -855,9 +1122,10 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream' -ForEach @(
|
||||
Context 'Outstream, audio, midi, video' -ForEach @(
|
||||
@{ Index = $vban_outA }
|
||||
# @{ Index = $vban_outM }
|
||||
@{ Index = $vban_outM }
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].name" -ForEach @(
|
||||
@{ Value = 'TestOut0'; Expected = 'TestOut0' }
|
||||
@@ -874,6 +1142,31 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.vban.outstream[$index].ip | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream, midi only' -ForEach @(
|
||||
@{ Index = $vban_outM }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].route" -ForEach @(
|
||||
@{ Value = 'aux_in'; Expected = 'aux_in' }
|
||||
@{ Value = 'all_in'; Expected = 'all_in' }
|
||||
@{ Value = 'midi_out'; Expected = 'midi_out' }
|
||||
) {
|
||||
$vmr.vban.outstream[$index].route = $value
|
||||
$vmr.vban.outstream[$index].route | Should -Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Outstream, video only' -ForEach @(
|
||||
@{ Index = $vban_outV }
|
||||
) {
|
||||
It "Should set vban.outstream[$index].vformat" -ForEach @(
|
||||
@{ Value = 'png'; Expected = 'png' }
|
||||
@{ Value = 'jpg'; Expected = 'jpg' }
|
||||
) {
|
||||
$vmr.vban.outstream[$index].vformat = $value
|
||||
$vmr.vban.outstream[$index].vformat | Should -Be $expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Recorder' -Skip:$ifBasic {
|
||||
@@ -884,13 +1177,19 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
$vmr.recorder.prefix = $prefix
|
||||
$vmr.recorder.filetype = $filetype
|
||||
|
||||
$start = Get-Date
|
||||
$vmr.recorder.state = 'record'
|
||||
Start-Sleep -Milliseconds 10
|
||||
$stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date)
|
||||
$vmr.recorder.state | Should -Be 'record'
|
||||
Start-Sleep -Milliseconds 2000
|
||||
|
||||
$tmp = [System.IO.Path]::Combine($recDir, ("{0} {1}.{2}" -f $prefix, $stamp, $filetype))
|
||||
$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.state = 'stop'
|
||||
$vmr.recorder.eject()
|
||||
@@ -978,12 +1277,18 @@ Describe -Tag 'higher', -TestName 'All Higher Tests' {
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
$start = Get-Date
|
||||
$vmr.recorder.record()
|
||||
Start-Sleep -Milliseconds 10
|
||||
$stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date)
|
||||
Start-Sleep -Milliseconds 2000
|
||||
|
||||
$tmp = [System.IO.Path]::Combine($recDir, ("{0} {1}.{2}" -f $prefix, $stamp, $filetype))
|
||||
$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.pause()
|
||||
Start-Sleep -Milliseconds 500
|
||||
|
||||
@@ -11,12 +11,18 @@ function Test-RecDir ([object]$vmr, [string]$recDir) {
|
||||
|
||||
|
||||
try {
|
||||
$start = Get-Date
|
||||
$vmr.recorder.record()
|
||||
Start-Sleep -Milliseconds 10
|
||||
$stamp = '{0:yyyy-MM-dd} at {0:HH}h{0:mm}m{0:ss}s' -f (Get-Date)
|
||||
Start-Sleep -Milliseconds 2000
|
||||
|
||||
$tmp = Join-Path $recDir ("{0} {1}.{2}" -f $prefix, $stamp, $filetype)
|
||||
$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()
|
||||
@@ -53,6 +59,7 @@ function main() {
|
||||
$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
|
||||
|
||||
Reference in New Issue
Block a user