Skip to content

Commit 3d7c45c

Browse files
committed
added solo control commands
1 parent 7c9bf1f commit 3d7c45c

File tree

6 files changed

+257
-23
lines changed

6 files changed

+257
-23
lines changed

src/actions/common.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
GetPanoramaDeltaSlider,
1515
GetColorDropdown,
1616
GetNumberField,
17+
GetSoloDropdown,
1718
} from '../choices/common.js'
1819
import { getNodeNumber, getNumber, runTransition } from './utils.js'
1920
import { InstanceBaseExt } from '../types.js'
@@ -45,6 +46,9 @@ export enum CommonActions {
4546
RestorePanorama = 'restore-panorama',
4647
DeltaPanorama = 'panorama-delta',
4748
UndoDeltaPanorama = 'undo-panorama',
49+
// Solo
50+
SetSolo = 'set-solo',
51+
ClearSolo = 'clear-solo',
4852
//////////// SEND
4953
SetSendMute = 'set-send-mute',
5054
// Send Fader
@@ -409,6 +413,50 @@ export function createCommonActions(self: InstanceBaseExt<WingConfig>): Companio
409413
ensureLoaded(cmd)
410414
},
411415
},
416+
////////////////////////////////////////////////////////////////
417+
// Solo
418+
////////////////////////////////////////////////////////////////
419+
[CommonActions.SetSolo]: {
420+
name: 'Set Solo',
421+
description: 'Set the solo state for a channel, aux, bux, matrix or main',
422+
options: [GetDropdown('Selection', 'sel', allChannels), GetSoloDropdown('solo')],
423+
callback: async (event) => {
424+
const sel = event.options.sel as string
425+
const cmd = ActionUtil.getSoloCommand(sel, getNodeNumber(event, 'sel'))
426+
const val = ActionUtil.getNumber(event, 'solo')
427+
const currentVal = StateUtil.getBooleanFromState(cmd, state)
428+
if (val < 2) {
429+
send(cmd, val)
430+
} else {
431+
send(cmd, Number(!currentVal))
432+
}
433+
},
434+
subscribe: (event) => {
435+
const sel = event.options.sel as string
436+
const cmd = ActionUtil.getSoloCommand(sel, getNodeNumber(event, 'sel'))
437+
ensureLoaded(cmd)
438+
},
439+
},
440+
[CommonActions.ClearSolo]: {
441+
name: 'Clear Solo',
442+
description: 'Clear the Solo from all channels, auxes, busses, matrices and mains.',
443+
options: [],
444+
callback: async (_) => {
445+
const extractNumber = (id: string): number | null => {
446+
const match = id.match(/\/(\d+)$/)
447+
return match ? parseInt(match[1], 10) : null
448+
}
449+
450+
for (const channel of allChannels) {
451+
const id = channel.id as string
452+
const number = extractNumber(id)
453+
if (number !== null) {
454+
const cmd = ActionUtil.getSoloCommand(id, number)
455+
send(cmd, 0)
456+
}
457+
}
458+
},
459+
},
412460

413461
////////////////////////////////////////////////////////////////
414462
// Send Fader

src/actions/config.ts

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { CompanionActionDefinition } from '@companion-module/base'
2+
import { SetRequired } from 'type-fest' // eslint-disable-line n/no-missing-import
3+
4+
export type CompanionActionWithCallback = SetRequired<CompanionActionDefinition, 'callback'>
5+
6+
import { CompanionActionDefinitions } from '@companion-module/base'
7+
import { GetDropdown, GetMuteDropdown } from '../choices/common.js'
8+
import { InstanceBaseExt } from '../types.js'
9+
import { WingConfig } from '../config.js'
10+
import * as ActionUtil from './utils.js'
11+
import { ConfigurationCommands } from '../commands/config.js'
12+
import { StateUtil } from '../state/index.js'
13+
import { getIdLabelPair } from '../choices/utils.js'
14+
15+
export enum CommonActions {
16+
// Solo
17+
SetSoloMute = 'set-solo-mute',
18+
SetSoloDim = 'set-solo-dim',
19+
SetSoloMono = 'set-solo-mono',
20+
SetSoloLRSwap = 'set-solo-swap',
21+
}
22+
23+
export function createConfigurationActions(self: InstanceBaseExt<WingConfig>): CompanionActionDefinitions {
24+
const send = self.sendCommand
25+
const ensureLoaded = self.ensureLoaded
26+
const state = self.state
27+
28+
const actions: { [id in CommonActions]: CompanionActionWithCallback | undefined } = {
29+
////////////////////////////////////////////////////////////////
30+
// Solo
31+
////////////////////////////////////////////////////////////////
32+
[CommonActions.SetSoloMute]: {
33+
name: 'Set Solo Mute',
34+
description: 'Set or toggle the mute state of the solo output.',
35+
options: [GetMuteDropdown('mute')],
36+
callback: async (event) => {
37+
const cmd = ConfigurationCommands.SoloMute()
38+
const val = ActionUtil.getNumber(event, 'mute')
39+
const currentVal = StateUtil.getBooleanFromState(cmd, state)
40+
if (val >= 2) {
41+
send(cmd, Number(!currentVal))
42+
} else {
43+
send(cmd, val)
44+
}
45+
},
46+
subscribe: (_) => {
47+
const cmd = ConfigurationCommands.SoloMute()
48+
ensureLoaded(cmd)
49+
},
50+
},
51+
[CommonActions.SetSoloDim]: {
52+
name: 'Set Solo Dim',
53+
description: 'Set or toggle the dim state of the solo output.',
54+
options: [
55+
GetDropdown(
56+
'Dim',
57+
'dim',
58+
[getIdLabelPair('1', 'On'), getIdLabelPair('0', 'Off'), getIdLabelPair('2', 'Toggle')],
59+
'1',
60+
),
61+
],
62+
callback: async (event) => {
63+
const cmd = ConfigurationCommands.SoloDim()
64+
const val = ActionUtil.getNumber(event, 'dim')
65+
const currentVal = StateUtil.getBooleanFromState(cmd, state)
66+
if (val >= 2) {
67+
send(cmd, Number(!currentVal))
68+
} else {
69+
send(cmd, val)
70+
}
71+
},
72+
subscribe: (_) => {
73+
const cmd = ConfigurationCommands.SoloDim()
74+
ensureLoaded(cmd)
75+
},
76+
},
77+
[CommonActions.SetSoloMono]: {
78+
name: 'Set Solo Mono',
79+
description: 'Set or toggle the mono state of the solo output.',
80+
options: [
81+
GetDropdown(
82+
'Mono',
83+
'mono',
84+
[getIdLabelPair('1', 'On'), getIdLabelPair('0', 'Off'), getIdLabelPair('2', 'Toggle')],
85+
'1',
86+
),
87+
],
88+
callback: async (event) => {
89+
const cmd = ConfigurationCommands.SoloMono()
90+
const val = ActionUtil.getNumber(event, 'mono')
91+
const currentVal = StateUtil.getBooleanFromState(cmd, state)
92+
if (val >= 2) {
93+
send(cmd, Number(!currentVal))
94+
} else {
95+
send(cmd, val)
96+
}
97+
},
98+
subscribe: (_) => {
99+
const cmd = ConfigurationCommands.SoloMono()
100+
ensureLoaded(cmd)
101+
},
102+
},
103+
[CommonActions.SetSoloLRSwap]: {
104+
name: 'Set Solo LR Swap',
105+
description: 'Set the left-right channel swap of the solo channel.',
106+
options: [
107+
GetDropdown(
108+
'Swap',
109+
'swap',
110+
[getIdLabelPair('1', 'Swap'), getIdLabelPair('0', "Don't Swap"), getIdLabelPair('2', 'Toggle')],
111+
'1',
112+
),
113+
],
114+
callback: async (event) => {
115+
const cmd = ConfigurationCommands.SoloLRSwap()
116+
const val = ActionUtil.getNumber(event, 'swap')
117+
const currentVal = StateUtil.getBooleanFromState(cmd, state)
118+
if (val >= 2) {
119+
send(cmd, Number(!currentVal))
120+
} else {
121+
send(cmd, val)
122+
}
123+
},
124+
subscribe: (_) => {
125+
const cmd = ConfigurationCommands.SoloLRSwap()
126+
ensureLoaded(cmd)
127+
},
128+
},
129+
}
130+
return actions
131+
}

src/actions/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CompanionActionDefinitions } from '@companion-module/base'
22
import { createChannelActions } from '../actions/channel.js'
3+
import { createConfigurationActions } from '../actions/config.js'
34
import { GetOtherActions as createOtherActions } from './other.js'
45
import { createBusActions as createBusActions } from './bus.js'
56
import { InstanceBaseExt } from '../types.js'
@@ -16,6 +17,7 @@ export function createActions(self: InstanceBaseExt<WingConfig>): CompanionActio
1617
...createBusActions(self),
1718
...createAuxActions(self),
1819
...createMainActions(self),
20+
...createConfigurationActions(self),
1921
}
2022

2123
return actions

src/actions/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,22 @@ export function getMuteCommand(sel: string, val: number): string {
129129
return cmd
130130
}
131131

132+
export function getSoloCommand(sel: string, val: number): string {
133+
let cmd = ''
134+
if (sel.startsWith('/ch')) {
135+
cmd = ChannelCommands.Solo(val)
136+
} else if (sel.startsWith('/aux')) {
137+
cmd = AuxCommands.Solo(val)
138+
} else if (sel.startsWith('/bus')) {
139+
cmd = BusCommands.Solo(val)
140+
} else if (sel.startsWith('/mtx')) {
141+
cmd = MatrixCommands.Solo(val)
142+
} else if (sel.startsWith('/main')) {
143+
cmd = MainCommands.Solo(val)
144+
}
145+
return cmd
146+
}
147+
132148
export function getFaderCommand(sel: string, val: number): string {
133149
let cmd = ''
134150
if (sel.startsWith('/ch')) {

src/choices/common.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,20 @@ export function GetMuteDropdown(id: string, label?: string, includeToggle?: bool
8080
const dropdown = GetDropdown(
8181
label ?? 'Mute',
8282
id,
83-
[getIdLabelPair('0', 'Unmute'), getIdLabelPair('1', 'Mute')],
83+
[getIdLabelPair('1', 'Mute'), getIdLabelPair('0', 'Unmute')],
84+
'1',
85+
'Select whether to Mute, Unmute or Toggle your selected target',
86+
)
87+
if (includeToggle == false) return dropdown
88+
89+
return { ...dropdown, choices: [...dropdown.choices, getIdLabelPair('2', 'Toggle')] }
90+
}
91+
92+
export function GetSoloDropdown(id: string, label?: string, includeToggle?: boolean): CompanionInputFieldDropdown {
93+
const dropdown = GetDropdown(
94+
label ?? 'Solo',
95+
id,
96+
[getIdLabelPair('1', 'On'), getIdLabelPair('0', 'Off')],
8497
'1',
8598
'Select whether to Mute, Unmute or Toggle your selected target',
8699
)

src/commands/config.ts

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,91 +102,115 @@ export namespace ConfigurationCommands {
102102
// Commands
103103
////////////////////////////////////////////////
104104

105+
export function ConfigNode(): string {
106+
return `/cfg`
107+
}
108+
105109
export function ClockRate(): string {
106-
return '/cfg/clkrate'
110+
return `${ConfigNode}/clkrate`
107111
}
108112

109113
export function ClockSource(): string {
110-
return '/cfg/clksrc'
114+
return `${ConfigNode}/clksrc`
111115
}
112116

113117
export function MainLink(): string {
114-
return '/cfg/mainlink'
118+
return `${ConfigNode}/mainlink`
115119
}
116120

117121
export function DcaGroup(): string {
118-
return '/cfg/dcamgrp'
122+
return `${ConfigNode}/dcamgrp`
119123
}
120124

121125
export function MuteOverride(): string {
122-
return '/cfg/muteovr'
126+
return `${ConfigNode}/muteovr`
123127
}
124128

125129
export function StartMute(): string {
126-
return '/cfg/startmute'
130+
return `${ConfigNode}/startmute`
127131
}
128132

129133
export function UsbConfig(): string {
130-
return '/cfg/usbacfg'
134+
return `${ConfigNode}/usbacfg`
131135
}
132136

133137
export function ScConfig(): string {
134-
return '/cfg/sccfg'
138+
return `${ConfigNode}/sccfg`
135139
}
136140

137141
export function MonitorEqGain(node: MonitorNode, band: MonitorEqBand): string {
138-
return `/cfg/mon/${node}/eq/${band}g`
142+
return `${ConfigNode}/mon/${node}/eq/${band}g`
139143
}
140144

141145
export function MonitorEqFrequency(node: MonitorNode, band: MonitorEqBand): string {
142-
return `/cfg/mon/${node}/eq/${band}f`
146+
return `${ConfigNode}/mon/${node}/eq/${band}f`
143147
}
144148

145149
export function MonitorEqQ(node: MonitorNode, band: MonitorEqBand): string {
146-
return `/cfg/mon/${node}/eq/${band}q`
150+
return `${ConfigNode}/mon/${node}/eq/${band}q`
147151
}
148152

149153
export function MonitorEqHighShelfGain(node: MonitorNode): string {
150-
return `/cfg/mon/${node}/eq/hsg`
154+
return `${ConfigNode}/mon/${node}/eq/hsg`
151155
}
152156

153157
export function MonitorEqHighShelfFrequency(node: MonitorNode): string {
154-
return `/cfg/mon/${node}/eq/hsf`
158+
return `${ConfigNode}/mon/${node}/eq/hsf`
155159
}
156160

157161
export function MonitorLimiterLevel(node: MonitorNode): string {
158-
return `/cfg/mon/${node}/lim`
162+
return `${ConfigNode}/mon/${node}/lim`
159163
}
160164

161165
export function MonitorDelayOn(node: MonitorNode): string {
162-
return `/cfg/mon/${node}/dly/on`
166+
return `${ConfigNode}/mon/${node}/dly/on`
163167
}
164168

165169
export function MonitorDelayMeters(node: MonitorNode): string {
166-
return `/cfg/mon/${node}/dly/m`
170+
return `${ConfigNode}/mon/${node}/dly/m`
167171
}
168172

169173
export function MonitorDelayDimLevel(node: MonitorNode): string {
170-
return `/cfg/mon/${node}/dim`
174+
return `${ConfigNode}/mon/${node}/dim`
171175
}
172176

173177
export function MonitorPflDim(node: MonitorNode): string {
174-
return `/cfg/mon/${node}/pfldim`
178+
return `${ConfigNode}/mon/${node}/pfldim`
175179
}
176180

177181
export function MonitorEqBandSoloTrim(node: MonitorNode): string {
178-
return `/cfg/mon/${node}/eqbdtrim`
182+
return `${ConfigNode}/mon/${node}/eqbdtrim`
179183
}
180184

181185
export function MonitorSourceLevel(node: MonitorNode): string {
182-
return `/cfg/mon/${node}/srclvl`
186+
return `${ConfigNode}/mon/${node}/srclvl`
183187
}
184188

185189
export function MonitorSourceMix(node: MonitorNode): string {
186-
return `/cfg/mon/${node}/srcmix`
190+
return `${ConfigNode}/mon/${node}/srcmix`
187191
}
188192

189193
export function MonitorSource(node: MonitorNode): string {
190-
return `/cfg/mon/${node}/src`
194+
return `${ConfigNode}/mon/${node}/src`
195+
}
196+
197+
export function SoloNode(): string {
198+
return `${ConfigNode()}/solo`
199+
}
200+
201+
export function SoloMute(): string {
202+
return `${SoloNode()}/mute`
203+
}
204+
205+
export function SoloDim(): string {
206+
return `${SoloNode()}/$dim`
207+
}
208+
209+
export function SoloMono(): string {
210+
return `${SoloNode()}/$mono`
211+
}
212+
213+
export function SoloLRSwap(): string {
214+
return `${SoloNode()}/$flip`
191215
}
192216
}

0 commit comments

Comments
 (0)