pblivingston d1dfe2de52 revert to user folder
should be faster this way, and it wasn't actually causing the problems i thought it was causing

pester tests pass for all kinds
2026-03-04 21:15:46 -05:00

207 lines
6.2 KiB
PowerShell

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) {
$v = $device.IsOutput -eq ($this.kindOfDevice -eq 'Output')
$d = $device.Driver
$n = $device.Name
if ($v -and $d -is [string] -and $n -is [string]) {
if ($d -eq '' -and $n -eq '') {
$this.Clear()
return
}
if ($d -in $this.drivers.Values) {
$this.Setter($d, $n)
return
}
}
Write-Warning "Invalid device object provided to Set method."
}
[void] Clear () {
$this.Setter('mme', '')
}
hidden $_driver = $($this | Add-Member ScriptProperty 'driver' `
{
if ([string]::IsNullOrEmpty($this.name)) { return '' }
$path = $this.remote.workingconfig
$oldTime = if (Test-Path $path) { (Get-Item $path).LastWriteTime } else { [DateTime]::MinValue }
$this.remote.Setter('Command.Save', $path)
$timeout = New-TimeSpan -Seconds 2
$sw = [Diagnostics.Stopwatch]::StartNew()
$line = $null
do {
if (Test-Path $path) {
$newTime = (Get-Item $path).LastWriteTime
if ($newTime -gt $oldTime) {
try {
$line = Get-Content $path | Select-String -Pattern "<$($this.kindOfDevice)Dev index='$($this.index + 1)'" -List
if ($line) { break }
}
catch {}
}
}
Start-Sleep -Milliseconds 20
} while ($sw.elapsed -lt $timeout)
$type = $null
if ($line -and $line.ToString() -match "type='(?<type>\d+)'") {
$type = $matches['type']
}
if ($type -notin $this.drivers.Keys) { return 'unknown' }
return $this.drivers[$type]
} `
{
Write-Warning ("ERROR: $($this.identifier()).driver is read only")
}
)
}