From 8e6ca6dec850d68463ee003abc60108f5d44345a Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Tue, 25 Jun 2024 14:12:13 +0100 Subject: [PATCH] v1.3.0 VBAN update --- README.md | 8 + companion/HELP.md | 5 +- companion/manifest.json | 2 +- package.json | 2 +- src/actions.ts | 362 +++++++++++++++++++++++++++++++++++++++- src/feedback.ts | 86 ++++++++++ src/index.ts | 3 +- src/utils.ts | 69 +++++++- src/variables.ts | 49 ++++++ 9 files changed, 576 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ee695a0..2b0919d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,14 @@ For a guide on setting up a proxy, refer to [HELP.md](./companion/HELP.md) # Recent Patches +**V1.3.0** +- Added `VBAN Settings`, `Macro Button`, and `Send Raw Command`, actions +- Added `VBAN` feedback +- Added Variables (`TYPE` is `instream` or `outstream`, and `INDEX` is 0 to 7) + - `vban_on` + - `vban_TYPE_INDEX_on`, `vban_TYPE_INDEX_name`, `vban_TYPE_INDEX_ip`, `vban_TYPE_INDEX_port`, `vban_TYPE_INDEX_sr`, `vban_TYPE_INDEX_channel`, `vban_TYPE_INDEX_bit`, `vban_TYPE_INDEX_quality`, `vban_TYPE_INDEX_route` +- Minor bug fixes + **V1.2.1** - Added node-gyp dependency diff --git a/companion/HELP.md b/companion/HELP.md index ffb0f16..1053d32 100644 --- a/companion/HELP.md +++ b/companion/HELP.md @@ -9,8 +9,9 @@ Companion interacts with the Voicemeeter API by searching for the install locati ## Prereuisuites NodeJS >= 18 -## Steps + +## Steps to run the Proxy (Only required if running Voicemeeter on a separate machine to Companion) 1. Download the [companion-module-vbaudio-voicemeeter repository](https://github.com/bitfocus/companion-module-vbaudio-voicemeeter). This can be done either by `git clone` or by clicking on the Code button, and then downloading the zip -2. In the directory you've cloned or unzipped the repo to, run `npm i`. This will download the modules dependencies +2. In the directory you've cloned or unzipped the repo to, run `npm i`. This will download the modules dependencies (NOTE: there may be additional dependencies separate from the module required to build it due to the nature of Voicemeeters API, if there is any issues feel free to reach out on the [Issues Page](https://github.com/bitfocus/companion-module-vbaudio-voicemeeter/issues)) 3. Run `node proxy` to start running the proxy on the default port of 8099, or use the `-p PORT` argument to specify a port, such as `node proxy -p 3000` 4. In Companion, create an instance for Voicemeeter and in the configuration set the IP and Port of where the proxy is running diff --git a/companion/manifest.json b/companion/manifest.json index 6d5a9b1..3fab20c 100644 --- a/companion/manifest.json +++ b/companion/manifest.json @@ -3,7 +3,7 @@ "name": "voicemeeter", "shortname": "Voicemeeter", "description": "Voicemeeter API Library and Proxy", - "version": "1.2.1", + "version": "0.0.0", "license": "MIT", "repository": "https://github.com/bitfocus/companion-module-vbaudio-voicemeeter.git", "bugs": "https://github.com/bitfocus/companion-module-vbaudio-voicemeeter/issues", diff --git a/package.json b/package.json index 8818aa3..80f7bf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "voicemeeter", - "version": "1.2.1", + "version": "1.3.0", "type": "commonjs", "main": "dist/index.js", "scripts": { diff --git a/src/actions.ts b/src/actions.ts index 429ff33..ef5b8eb 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -1,5 +1,5 @@ import { CompanionActionEvent, SomeCompanionActionInputField } from '@companion-module/base' -import { BusProperties, RecorderProperties, StripProperties } from 'voicemeeter-connector' +import { BusProperties, CommandButtons, RecorderProperties, StripProperties, VBANInstream, VBANOutstream } from 'voicemeeter-connector' import VoicemeeterInstance from './index' import { BusMode, getOptions } from './utils' @@ -27,6 +27,9 @@ export interface VoicemeeterActions { stripMono: VoicemeeterAction stripMute: VoicemeeterAction stripSolo: VoicemeeterAction + vbanSettings: VoicemeeterAction + macroButton: VoicemeeterAction + rawCommand: VoicemeeterAction utilSelectBus: VoicemeeterAction utilSelectStrip: VoicemeeterAction @@ -299,6 +302,42 @@ interface RecorderStateCallback { }> } +interface VbanSettingsCallback { + actionId: 'vbanSettings' + options: Readonly<{ + type: 'vban' | 'instream' | 'outstream' + index: string + inProperty: 'on' | 'name' | 'ip' | 'port' | 'quality' | 'route' + outProperty: 'on' | 'name' | 'ip' | 'port' | 'sr' | 'channel' | 'bit' | 'quality' | 'route' + adjustment: 'Toggle' | 'On' | 'Off' + name: string + ip: string + port: string + sr: '11025' | '16000' | '22050' | '24000' | '32000' | '44100' | '48000' | '64000' | '88200' | '96000' + channel: string + bit: '1' | '2' + quality: '0' | '1' | '2' | '3' | '4' + route: string + }> +} + +interface MacroButtonCallback { + actionId: 'macroButton' + options: Readonly<{ + id: string + type: 'state' | 'stateOnly' | 'trigger' | 'color' + state: boolean + color: string + }> +} + +interface RawCommandCallback { + actionId: 'rawCommand' + options: Readonly<{ + command: string + }> +} + interface UtilSelectBusCallback { actionId: 'utilSelectBus' options: Readonly<{ @@ -337,6 +376,9 @@ export type ActionCallbacks = | StripMonoCallback | StripMuteCallback | StripSoloCallback + | VbanSettingsCallback + | MacroButtonCallback + | RawCommandCallback | UtilSelectBusCallback | UtilSelectStripCallback @@ -671,7 +713,6 @@ export function getActions(instance: VoicemeeterInstance): VoicemeeterActions { if (action.options.type === 'Toggle') { value = instance.bus[bus].mute ? 0 : 1 } - console.log(instance.bus[bus].mute, action.options.type, value) instance.connection?.setBusParameter(bus, BusProperties.Mute, value) }, }, @@ -843,7 +884,7 @@ export function getActions(instance: VoicemeeterInstance): VoicemeeterActions { } else if (command === 'Save' || command === 'Load') { let path = action.options.path if (path === '') return - + if (path.includes(' ') && !(path.startsWith('"') && path.endsWith('"'))) { path = `"${[path]}"` } @@ -1680,6 +1721,319 @@ export function getActions(instance: VoicemeeterInstance): VoicemeeterActions { }, }, + vbanSettings: { + name: 'VBAN Settings', + description: 'Control various settings of VBAN and each In/Out stream', + options: [ + { + type: 'dropdown', + label: 'Type', + id: 'type', + default: 'vban', + choices: [ + { id: 'vban', label: 'VBAN' }, + { id: 'instream', label: 'VBAN Incoming Stream' }, + { id: 'outstream', label: 'VBAN Outgoing Stream' }, + ] + }, + { + type: 'textinput', + label: 'Stream Index (0 to 7)', + id: 'index', + default: '0', + useVariables: true, + isVisible: (options) => options.type === 'instream' || options.type === 'outstream' + }, + { + type: 'dropdown', + label: 'Property', + id: 'inProperty', + default: 'on', + choices: [ + { id: 'on', label: 'On/Off' }, + { id: 'name', label: 'Name' }, + { id: 'ip', label: 'IP' }, + { id: 'port', label: 'Port' }, + { id: 'quality', label: 'Quality' }, + { id: 'route', label: 'Route' }, + ], + isVisible: (options) => { + return options.type === 'instream' + } + }, + { + type: 'dropdown', + label: 'Property', + id: 'outProperty', + default: 'on', + choices: [ + { id: 'on', label: 'On/Off' }, + { id: 'name', label: 'Name' }, + { id: 'ip', label: 'IP' }, + { id: 'port', label: 'Port' }, + { id: 'sr', label: 'Sample Rate' }, + { id: 'channel', label: 'Channel' }, + { id: 'bit', label: 'Data Type' }, + { id: 'quality', label: 'Quality' }, + { id: 'route', label: 'Route' }, + ], + isVisible: (options) => { + return options.type === 'outstream' + } + }, + { + type: 'dropdown', + label: 'Toggle/On/Off', + id: 'adjustment', + default: 'Toggle', + choices: ['Toggle', 'On', 'Off'].map((type) => ({ id: type, label: type })), + isVisible: (options) => { + return options.type === 'vban' || (options.type === 'instream' && options.inProperty === 'on') || (options.type === 'outstream' && options.outProperty === 'on') + } + }, + { + type: 'textinput', + label: 'Stream Name', + id: 'name', + default: 'StreamX', + useVariables: true, + isVisible: (options) => (options.type === 'instream' && options.inProperty === 'name') || (options.type === 'outstream' && options.outProperty === 'name') + }, + { + type: 'textinput', + label: 'IP', + id: 'ip', + default: '0.0.0.0', + useVariables: true, + isVisible: (options) => (options.type === 'instream' && options.inProperty === 'ip') || (options.type === 'outstream' && options.outProperty === 'ip') + }, + { + type: 'textinput', + label: 'Port', + id: 'port', + default: '6980', + useVariables: true, + isVisible: (options) => (options.type === 'instream' && options.inProperty === 'port') || (options.type === 'outstream' && options.outProperty === 'port') + }, + { + type: 'dropdown', + label: 'Sample Rate', + id: 'sr', + default: '11025', + choices: [ + { id: '11025', label: '11025 Hz' }, + { id: '16000', label: '16000 Hz' }, + { id: '22050', label: '22050 Hz' }, + { id: '24000', label: '24000 Hz' }, + { id: '32000', label: '32000 Hz' }, + { id: '44100', label: '44100 Hz' }, + { id: '48000', label: '48000 Hz' }, + { id: '64000', label: '64000 Hz' }, + { id: '88200', label: '88200 Hz' }, + { id: '96000', label: '96000 Hz' }, + ], + isVisible: (options) => options.type === 'outstream' && options.outProperty === 'sr' + }, + { + type: 'textinput', + label: 'Channel (1 to 8)', + id: 'channel', + default: '2', + useVariables: true, + isVisible: (options) => options.type === 'outstream' && options.outProperty === 'channel' + }, + { + type: 'dropdown', + label: 'Bit Resolution / Data Format', + id: 'bit', + default: '1', + choices: [ + { id: '1', label: '16 bit PCM' }, + { id: '2', label: '24 bit PCM' }, + ], + isVisible: (options) => options.type === 'outstream' && options.outProperty === 'bit' + }, + { + type: 'dropdown', + label: 'Quality', + id: 'quality', + default: '0', + choices: [ + { id: '0', label: 'Optimal' }, + { id: '1', label: 'Fast' }, + { id: '2', label: 'Medium' }, + { id: '3', label: 'Slow' }, + { id: '4', label: 'Very Slow' }, + ], + isVisible: (options) => (options.type === 'instream' && options.inProperty === 'quality') || (options.type === 'outstream' && options.outProperty === 'quality') + }, + { + type: 'textinput', + label: 'Strip/Bus (0 to 8)', + id: 'route', + default: '0', + useVariables: true, + isVisible: (options) => (options.type === 'instream' && options.inProperty === 'route') || (options.type === 'outstream' && options.outProperty === 'route') + }, + ], + callback: async (action) => { + if (action.options.type === 'vban') { + let state = instance.connection?.getVBANParameter() + let adjustment = state === 0 ? 1 : 0 + if (action.options.adjustment === 'On') adjustment = 1 + if (action.options.adjustment === 'Off') adjustment = 0 + + if (state !== adjustment) instance.connection?.setVBANParameter(adjustment) + } else { + let index: number | string = await instance.parseVariablesInString(action.options.index) + index = parseInt(index, 10) + + if (isNaN(index)) { + instance.log('warn', `VBAN Settings must have a valid index (0 to 7)`) + return + } + + if (action.options.type === 'instream') { + if (action.options.inProperty === 'on') { + let state = instance.connection?.getVBANInstreamParameter(index, VBANInstream.On) + let adjustment = state === 0 ? 1 : 0 + if (action.options.adjustment === 'On') adjustment = 1 + if (action.options.adjustment === 'Off') adjustment = 0 + if (state !== adjustment) instance.connection?.setVBANInstreamParameter(index, VBANInstream.On, adjustment) + } else if (action.options.inProperty === 'name') { + let value = await instance.parseVariablesInString(action.options.name) + instance.connection?.setVBANInstreamParameter(index, VBANInstream.Name, value) + } else if (action.options.inProperty === 'ip') { + let value = await instance.parseVariablesInString(action.options.ip) + instance.connection?.setVBANInstreamParameter(index, VBANInstream.IP, value) + } else if (action.options.inProperty === 'port') { + let value = await instance.parseVariablesInString(action.options.port) + instance.connection?.setVBANInstreamParameter(index, VBANInstream.Port, value) + } else if (action.options.inProperty === 'quality') { + instance.connection?.setVBANInstreamParameter(index, VBANInstream.Quality, action.options.quality) + } else if (action.options.inProperty === 'route') { + let value = await instance.parseVariablesInString(action.options.route) + instance.connection?.setVBANInstreamParameter(index, VBANInstream.Route, value) + } + } else { + if (action.options.outProperty === 'on') { + let state = instance.connection?.getVBANOutstreamParameter(index, VBANOutstream.On) + let adjustment = state === 0 ? 1 : 0 + if (action.options.adjustment === 'On') adjustment = 1 + if (action.options.adjustment === 'Off') adjustment = 0 + if (state !== adjustment) instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.On, adjustment) + } else if (action.options.outProperty === 'name') { + let value = await instance.parseVariablesInString(action.options.name) + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Name, value) + } else if (action.options.outProperty === 'ip') { + let value = await instance.parseVariablesInString(action.options.ip) + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.IP, value) + } else if (action.options.outProperty === 'port') { + let value = await instance.parseVariablesInString(action.options.port) + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Port, value) + } else if (action.options.outProperty === 'sr') { + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.SR, action.options.sr) + } else if (action.options.outProperty === 'channel') { + let value = await instance.parseVariablesInString(action.options.channel) + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Channel, value) + } else if (action.options.outProperty === 'bit') { + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Bit, action.options.bit) + } else if (action.options.outProperty === 'quality') { + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Quality, action.options.quality) + } else if (action.options.outProperty === 'route') { + let value = await instance.parseVariablesInString(action.options.route) + instance.connection?.setVBANOutstreamParameter(index, VBANOutstream.Route, value) + } + } + + } + } + }, + + macroButton: { + name: 'Macro Button', + description: '', + options: [ + { + type: 'textinput', + label: 'Button ID (0 based index)', + id: 'id', + default: '0', + useVariables: true, + }, + { + type: 'dropdown', + label: 'Type', + id: 'type', + default: 'state', + choices: [ + { id: 'state', label: 'Macro Button State' }, + { id: 'stateOnly', label: 'Change button state only' }, + { id: 'trigger', label: 'Trigger State' }, + { id: 'color', label: 'Color' }, + ] + }, + { + type: 'checkbox', + label: 'State', + id: 'state', + default: false, + isVisible: (options) => options.type !== 'color' + }, + { + type: 'textinput', + label: 'Color (0 to 8)', + id: 'color', + default: '0', + useVariables: true, + isVisible: (options) => options.type === 'color' + }, + ], + callback: async (action) => { + let id: number | string = await instance.parseVariablesInString(action.options.id) + id = parseInt(id, 10) + + if (isNaN(id)) { + instance.log('warn', 'Macro Button id must be a number') + return + } + + const value = action.options.state ? 1 : 0 + + if (action.options.type === 'state') { + instance.connection?.executeButtonAction(id, CommandButtons.State, value) + } else if (action.options.type === 'stateOnly') { + instance.connection?.executeButtonAction(id, CommandButtons.StateOnly, value) + } else if (action.options.type === 'trigger') { + instance.connection?.executeButtonAction(id, CommandButtons.Trigger, value) + } else { + const color = await instance.parseVariablesInString(action.options.color) + let colorTest = parseInt(color, 10) + if (isNaN(colorTest) || colorTest < 0 || colorTest > 8) { + instance.log('warn', 'Macro Button Color value must be a number 0 to 8') + return + } + instance.connection?.executeButtonAction(id, CommandButtons.Color, color) + } + } + }, + + rawCommand: { + name: 'Send Raw Command', + description: `Send a raw command to Voicemeeter`, + options: [{ + type: 'textinput', + label: 'Command', + id: 'command', + default: '', + useVariables: true + }], + callback: async (action) => { + let command = await instance.parseVariablesInString(action.options.command) + instance.connection?.setRaw(command) + } + }, + utilSelectBus: { name: 'Util - Select Bus', description: 'For use in Companion actions/feedback/variables, not Voicemeeter', @@ -1711,6 +2065,6 @@ export function getActions(instance: VoicemeeterInstance): VoicemeeterActions { instance.checkFeedbacks('utilSelectedStrip', 'routing') instance.variables?.updateVariables() }, - }, + } } } diff --git a/src/feedback.ts b/src/feedback.ts index 4def213..da939b7 100644 --- a/src/feedback.ts +++ b/src/feedback.ts @@ -25,6 +25,7 @@ export interface VoicemeeterFeedbacks { stripMono: VoicemeeterFeedback stripMute: VoicemeeterFeedback stripSolo: VoicemeeterFeedback + vban: VoicemeeterFeedback utilSelectedBus: VoicemeeterFeedback utilSelectedStrip: VoicemeeterFeedback @@ -127,6 +128,16 @@ interface RoutingCallback { type RoutingDestination = 'A1' | 'A2' | 'A3' | 'A4' | 'A5' | 'B1' | 'B2' | 'B3' +interface VbanCallback { + feedbackId: 'vban' + options: Readonly<{ + type: 'vban' | 'instream' | 'outstream' + index: string + property: 'on' | 'route' + route: string + }> +} + interface UtilSelectedBusCallback { feedbackId: 'utilSelectedBus' options: Readonly<{ @@ -156,6 +167,7 @@ export type FeedbackCallbacks = | StripMonoCallback | StripMuteCallback | StripSoloCallback + | VbanCallback | UtilSelectedBusCallback | UtilSelectedStripCallback @@ -668,6 +680,80 @@ export function getFeedbacks(instance: VoicemeeterInstance): VoicemeeterFeedback }, }, + vban: { + type: 'boolean', + name: 'VBAN', + description: 'Indicate the VBAN, or VBAN Stream, state', + options: [ + { + type: 'dropdown', + label: 'Type', + id: 'type', + default: 'vban', + choices: [ + { id: 'vban', label: 'VBAN' }, + { id: 'instream', label: 'VBAN Incoming Stream' }, + { id: 'outstream', label: 'VBAN Outgoing Stream' }, + ] + }, + { + type: 'textinput', + label: 'Stream Index (0 to 7)', + id: 'index', + default: '0', + useVariables: true, + isVisible: (options) => options.type !== 'vban' + }, + { + type: 'dropdown', + label: 'Property', + id: 'property', + default: 'on', + choices: [ + { id: 'on', label: 'On/Off' }, + { id: 'route', label: 'Route' }, + ], + isVisible: (options) => { + return options.type !== 'vban' + } + }, + { + type: 'textinput', + label: 'Strip/Bus (0 to 8)', + id: 'route', + default: '0', + useVariables: true, + isVisible: (options) => options.type !== 'vban' && options.property === 'route' + }, + ], + defaultStyle: { + color: combineRgb(0, 0, 0), + bgcolor: combineRgb(0, 255, 0), + }, + callback: async (feedback) => { + if (feedback.options.type === 'vban') { + return instance.vban.on === 1 + } else { + let index: number | string = await instance.parseVariablesInString(feedback.options.index) + index = parseInt(index, 10) + + if (isNaN(index)) { + instance.log('warn', `VBAN streams must have a valid index (0 to 7)`) + return false + } + + if (feedback.options.property === 'on') { + return instance.vban[feedback.options.type][index]?.on === 1 + } else { + let route: number | string = await instance.parseVariablesInString(feedback.options.route) + route = parseInt(route, 10) + + return instance.vban[feedback.options.type][index]?.route === route + } + } + } + }, + utilSelectedBus: { type: 'boolean', name: 'Util - Selected Bus', diff --git a/src/index.ts b/src/index.ts index 6b65fa4..cccc229 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ import { getFeedbacks } from './feedback' import { httpHandler } from './http' import { getPresets } from './presets' import { getUpgrades } from './upgrade' -import { Bus, Strip, ProxyConnection, getAllData, parseVersion, VoicemeeterType } from './utils' +import { Bus, Strip, ProxyConnection, getAllData, parseVersion, VBAN, VoicemeeterType } from './utils' import { Variables } from './variables' interface Device { @@ -41,6 +41,7 @@ class VoicemeeterInstance extends InstanceBase { public type: VoicemeeterType = '' private updateNeeded: boolean = false private updateHold: NodeJS.Timer | null = null + public vban: VBAN = { on: 0, instream: [], outstream: [] } public version = '' private levelsInterval: NodeJS.Timer | null = null diff --git a/src/utils.ts b/src/utils.ts index 5020d01..2950f2e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ import { CompanionInputFieldDropdown } from '@companion-module/base' -import { BusProperties, StripProperties, RecorderProperties } from 'voicemeeter-connector' +import { BusProperties, StripProperties, RecorderProperties, VBANInstream, VBANOutstream } from 'voicemeeter-connector' import VoicemeeterInstance from './' export interface Bus { @@ -141,6 +141,36 @@ export interface Strip { levelsHold: number } +export interface VBAN { + on: number + instream: VBANInstream[] + outstream: VBANOutstream[] +} + +interface VBANInstream { + on: number + name: number + ip: number + port: number + sr: number + channel: number + bit: number + quality: number + route: number +} + +interface VBANOutstream { + on: number + name: number + ip: number + port: number + sr: number + channel: number + bit: number + quality: number + route: number +} + export interface ProxyConnection { disconnect(): void executeCommandAction(property: string, value: any): any @@ -152,9 +182,16 @@ export interface ProxyConnection { getLevels(type: 0 | 1 | 2 | 3, id: number): any getRecorderParameter(property: string): any getStripParameter(index: number, property: string): any + getVBANParameter(): any + getVBANInstreamParameter(index: number, property: string): any + getVBANOutstreamParameter(index: number, property: string): any setBusParameter(index: number, property: string, value: any): any setRecorderParameter(property: string, value: any): any setStripParameter(index: number, property: string, value: any): any + setVBANParameter(value: any): any + setVBANInstreamParameter(index: number, property: string, value: any): any + setVBANOutstreamParameter(index: number, property: string, value: any): any + setRaw(value: string): any updateDeviceList(): void $inputDevices: [] $outputDevices: [] @@ -374,6 +411,36 @@ export const getAllData = (instance: VoicemeeterInstance) => { fileType: instance.connection?.getRecorderParameter(RecorderProperties.FileType), gain: instance.connection?.getRecorderParameter(RecorderProperties.Gain), } + + instance.vban.on = instance.connection?.getVBANParameter() + for (let i = 0; i < 8; i++) { + const instream: VBANInstream = { + on: instance.connection?.getVBANInstreamParameter(i, VBANInstream.On), + name: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Name), + ip: instance.connection?.getVBANInstreamParameter(i, VBANInstream.IP), + port: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Port), + sr: instance.connection?.getVBANInstreamParameter(i, VBANInstream.SR), + channel: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Channel), + bit: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Bit), + quality: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Quality), + route: instance.connection?.getVBANInstreamParameter(i, VBANInstream.Route), + } + + const outstream: VBANOutstream = { + on: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.On), + name: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Name), + ip: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.IP), + port: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Port), + sr: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.SR), + channel: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Channel), + bit: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Bit), + quality: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Quality), + route: instance.connection?.getVBANOutstreamParameter(i, VBANOutstream.Route), + } + + instance.vban.instream[i] = instream + instance.vban.outstream[i] = outstream + } } // Force options to have a default to prevent sending undefined values diff --git a/src/variables.ts b/src/variables.ts index 0225299..66b6643 100644 --- a/src/variables.ts +++ b/src/variables.ts @@ -148,6 +148,29 @@ export class Variables { variables.add({ name: `Strip ${name} Post FX 2`, variableId: `strip_${name.toLowerCase()}_post_fx2` }) } + variables.add({ name: 'VBAN On/Off', variableId: 'vban_on' }) + for (let i = 0; i < 8; i++) { + variables.add({ name: `VBAN Instream ${i} On/Off`, variableId: `vban_instream_${i}_on` }) + variables.add({ name: `VBAN Instream ${i} Name`, variableId: `vban_instream_${i}_name` }) + variables.add({ name: `VBAN Instream ${i} IP`, variableId: `vban_instream_${i}_ip` }) + variables.add({ name: `VBAN Instream ${i} Port`, variableId: `vban_instream_${i}_port` }) + variables.add({ name: `VBAN Instream ${i} Sample Rate`, variableId: `vban_instream_${i}_sr` }) + variables.add({ name: `VBAN Instream ${i} Channel`, variableId: `vban_instream_${i}_channel` }) + variables.add({ name: `VBAN Instream ${i} Bit`, variableId: `vban_instream_${i}_bit` }) + variables.add({ name: `VBAN Instream ${i} Quality`, variableId: `vban_instream_${i}_quality` }) + variables.add({ name: `VBAN Instream ${i} Route`, variableId: `vban_instream_${i}_route` }) + + variables.add({ name: `VBAN Outstream ${i} On/Off`, variableId: `vban_outstream_${i}_on` }) + variables.add({ name: `VBAN Outstream ${i} Name`, variableId: `vban_outstream_${i}_name` }) + variables.add({ name: `VBAN Outstream ${i} IP`, variableId: `vban_outstream_${i}_ip` }) + variables.add({ name: `VBAN Outstream ${i} Port`, variableId: `vban_outstream_${i}_port` }) + variables.add({ name: `VBAN Outstream ${i} Sample Rate`, variableId: `vban_outstream_${i}_sr` }) + variables.add({ name: `VBAN Outstream ${i} Channel`, variableId: `vban_outstream_${i}_channel` }) + variables.add({ name: `VBAN Outstream ${i} Bit`, variableId: `vban_outstream_${i}_bit` }) + variables.add({ name: `VBAN Outstream ${i} Quality`, variableId: `vban_outstream_${i}_quality` }) + variables.add({ name: `VBAN Outstream ${i} Route`, variableId: `vban_outstream_${i}_route` }) + } + //this.currentDefinitions = new Set(variables) this.instance.setVariableDefinitions([...variables]) @@ -243,6 +266,32 @@ export class Variables { newVariables[`strip_${i + 1}_post_fx2`] = this.instance.strip[i]?.postFx2.toString() } + newVariables[`vban_on`] = this.instance.vban.on + for (let i = 0; i < 8; i++) { + if (this.instance.vban.instream[i]) { + newVariables[`vban_instream_${i}_on`] = this.instance.vban.instream[i].on + newVariables[`vban_instream_${i}_name`] = this.instance.vban.instream[i].name + newVariables[`vban_instream_${i}_ip`] = this.instance.vban.instream[i].ip + newVariables[`vban_instream_${i}_port`] = this.instance.vban.instream[i].port + newVariables[`vban_instream_${i}_sr`] = this.instance.vban.instream[i].sr + newVariables[`vban_instream_${i}_channel`] = this.instance.vban.instream[i].channel + newVariables[`vban_instream_${i}_bit`] = this.instance.vban.instream[i].bit + newVariables[`vban_instream_${i}_quality`] = this.instance.vban.instream[i].quality + newVariables[`vban_instream_${i}_route`] = this.instance.vban.instream[i].route + } + if (this.instance.vban.outstream[i]) { + newVariables[`vban_outstream_${i}_on`] = this.instance.vban.outstream[i].on + newVariables[`vban_outstream_${i}_name`] = this.instance.vban.outstream[i].name + newVariables[`vban_outstream_${i}_ip`] = this.instance.vban.outstream[i].ip + newVariables[`vban_outstream_${i}_port`] = this.instance.vban.outstream[i].port + newVariables[`vban_outstream_${i}_sr`] = this.instance.vban.outstream[i].sr + newVariables[`vban_outstream_${i}_channel`] = this.instance.vban.outstream[i].channel + newVariables[`vban_outstream_${i}_bit`] = this.instance.vban.outstream[i].bit + newVariables[`vban_outstream_${i}_quality`] = this.instance.vban.outstream[i].quality + newVariables[`vban_outstream_${i}_route`] = this.instance.vban.outstream[i].route + } + } + this.set(newVariables) this.updateDefinitions() }