modified: .gitignore
modified: src/Logger.ts modified: src/VMR/Bus.ts modified: src/VMR/Control.ts new file: src/VMR/Device.ts modified: src/VMR/Remote.ts modified: src/VMR/Strip.ts modified: src/decorators/minVersion.ts modified: src/decorators/validation.ts modified: src/main.ts new file: src/utils/Error.ts modified: src/utils/getEnvVariable.ts modified: src/variables.ts
This commit is contained in:
parent
fd2f5df26b
commit
5b2df1c3f6
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ node_modules
|
||||||
.vscode
|
.vscode
|
||||||
logs
|
logs
|
||||||
VoicemeeterRemote.h
|
VoicemeeterRemote.h
|
||||||
|
.hintrc
|
|
@ -2,25 +2,34 @@ import path from "path";
|
||||||
import { DEBUG } from "./variables";
|
import { DEBUG } from "./variables";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|
||||||
|
export type LogOptions = Omit<Parameters<Logger["writeEntry"]>["0"], "type">;
|
||||||
|
|
||||||
export class Logger {
|
export class Logger {
|
||||||
public currentLogFile: string;
|
public currentLogFile: string;
|
||||||
public tag?: string;
|
public tag?: string;
|
||||||
private get pathToLogFile(): string {
|
public divider: string = "\n";
|
||||||
return path.join(__dirname, "../log", this.currentLogFile);
|
private get pathToLogFolder(): string {
|
||||||
|
return path.join(__dirname, "../logs");
|
||||||
|
}
|
||||||
|
private get pathToCurrentLog(): string {
|
||||||
|
return path.join(__dirname, "../logs", this.currentLogFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(options?: { tag?: string }) {
|
constructor(options?: { tag?: string; divider?: string }) {
|
||||||
this.currentLogFile = this.createNewLogFile();
|
this.currentLogFile = this.createNewLogFile();
|
||||||
if (options !== undefined) {
|
if (options === undefined) return;
|
||||||
this.tag = options.tag;
|
if (options.tag !== undefined) this.tag = options.tag;
|
||||||
}
|
if (options.divider !== undefined) this.divider = options.divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createNewLogFile() {
|
private createNewLogFile() {
|
||||||
const date = new Date().toISOString().split("T");
|
const date = new Date().toISOString().split("T");
|
||||||
date[1] = date[1].split(".")[0].replaceAll(":", "-");
|
date[1] = date[1].split(".")[0].replaceAll(":", "-");
|
||||||
const fileName = `${date}.log`;
|
const fileName = `${date.join("-")}.log`;
|
||||||
fs.writeFileSync(this.pathToLogFile, "");
|
const newLogPath = path.join(this.pathToLogFolder, fileName);
|
||||||
|
if (!fs.existsSync(newLogPath)) fs.writeFileSync(newLogPath, "");
|
||||||
|
const latestLogPath = path.join(this.pathToLogFolder, "./latest.log");
|
||||||
|
if (fs.existsSync(latestLogPath)) fs.writeFileSync(latestLogPath, "");
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
private toString(object: any) {
|
private toString(object: any) {
|
||||||
|
@ -32,11 +41,14 @@ export class Logger {
|
||||||
else if (typeof object === "string") return object;
|
else if (typeof object === "string") return object;
|
||||||
return "Cannot transfrom object to string";
|
return "Cannot transfrom object to string";
|
||||||
}
|
}
|
||||||
private writeEntryToFile(
|
private appendTextToLog(content: string) {
|
||||||
|
fs.appendFileSync(this.pathToCurrentLog, content);
|
||||||
|
fs.appendFileSync(path.join(this.pathToLogFolder, "./latest.log"), content);
|
||||||
|
}
|
||||||
|
private writeEntry(
|
||||||
options: {
|
options: {
|
||||||
tag?: string;
|
tag?: string;
|
||||||
type: "log" | "error" | "warn" | "info";
|
type: "log" | "error" | "warn" | "info";
|
||||||
divider?: string;
|
|
||||||
},
|
},
|
||||||
...args: any
|
...args: any
|
||||||
) {
|
) {
|
||||||
|
@ -50,29 +62,38 @@ export class Logger {
|
||||||
dateStyle: "short",
|
dateStyle: "short",
|
||||||
timeStyle: "medium",
|
timeStyle: "medium",
|
||||||
});
|
});
|
||||||
const divider = options.divider === undefined ? "\n\t" : options.divider;
|
|
||||||
let string = `[${dateString}] `;
|
let string = `[${dateString}] `;
|
||||||
if (this.tag !== undefined) string += `[LTAG: ${this.tag}`;
|
const tags = [
|
||||||
if (options.tag !== undefined) string += ` TAG: ${options.tag}] `;
|
["LTAG", this.tag],
|
||||||
else string += "] ";
|
["TAG", options.tag],
|
||||||
|
].filter((i) => i[1] !== undefined);
|
||||||
|
if (tags.length > 0) {
|
||||||
|
string += "[";
|
||||||
|
for (const [tagName, tag] of tags) {
|
||||||
|
string += `${tagName}: ${tag}`;
|
||||||
|
}
|
||||||
|
string += "] ";
|
||||||
|
}
|
||||||
string += `[${options.type.toUpperCase()}] `;
|
string += `[${options.type.toUpperCase()}] `;
|
||||||
string += strings.join(divider);
|
string += strings.join(this.divider + "\t");
|
||||||
fs.appendFileSync(this.pathToLogFile, string);
|
string += this.divider;
|
||||||
|
this.appendTextToLog(string);
|
||||||
}
|
}
|
||||||
public log(...args: any) {
|
public log(options?: LogOptions, ...args: any) {
|
||||||
if (!DEBUG) console.log(...args);
|
if (!DEBUG) console.log(...args);
|
||||||
this.writeEntryToFile({ type: "log" }, ...args);
|
this.writeEntry({ type: "log", ...options }, ...args);
|
||||||
}
|
}
|
||||||
public error(...args: any) {
|
public error(options?: LogOptions, ...args: any) {
|
||||||
if (!DEBUG) console.error(...args);
|
if (!DEBUG) console.error(...args);
|
||||||
this.writeEntryToFile({ type: "error" }, ...args);
|
this.writeEntry({ type: "error", ...options }, ...args);
|
||||||
}
|
}
|
||||||
public warn(...args: any) {
|
public warn(options?: LogOptions, ...args: any) {
|
||||||
if (!DEBUG) console.warn(...args);
|
if (!DEBUG) console.warn(...args);
|
||||||
this.writeEntryToFile({ type: "warn" }, ...args);
|
this.writeEntry({ type: "warn", ...options }, ...args);
|
||||||
}
|
}
|
||||||
public info(...args: any) {
|
public info(options?: LogOptions, ...args: any) {
|
||||||
if (!DEBUG) console.info(...args);
|
if (!DEBUG) console.info(...args);
|
||||||
this.writeEntryToFile({ type: "info" }, ...args);
|
this.writeEntry({ type: "info", ...options }, ...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export const logger = new Logger({});
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { VMObject } from "./VMObject";
|
||||||
|
import { minType } from "../decorators/minVersion";
|
||||||
|
import { validation } from "../decorators/validation";
|
||||||
|
import { Control } from "./Control";
|
||||||
|
|
||||||
|
export class Strip extends VMObject {
|
||||||
|
@validation()
|
||||||
|
public get Mono(): boolean {
|
||||||
|
return this.getParamValueBoolean(this.buildParameterString("Mono"))[1];
|
||||||
|
}
|
||||||
|
public set Mono(v: boolean) {
|
||||||
|
this.setParamValueBoolean(this.buildParameterString("Mono"), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@validation()
|
||||||
|
public get Mute(): boolean {
|
||||||
|
return this.getParamValueBoolean(this.buildParameterString("Mute"))[1];
|
||||||
|
}
|
||||||
|
public set Mute(v: boolean) {
|
||||||
|
this.setParamValueBoolean(this.buildParameterString("Mute"), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@validation()
|
||||||
|
public get EQEnabled(): boolean {
|
||||||
|
return this.getParamValueBoolean(this.buildParameterString("EQ", "on"))[1];
|
||||||
|
}
|
||||||
|
public set EQEnabled(v: boolean) {
|
||||||
|
this.setParamValueBoolean(this.buildParameterString("EQ", "on"), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@validation()
|
||||||
|
public get EQVariant(): boolean {
|
||||||
|
return this.getParamValueBoolean(this.buildParameterString("EQ", "AB"))[1];
|
||||||
|
}
|
||||||
|
public set EQVariant(v: boolean) {
|
||||||
|
this.setParamValueBoolean(this.buildParameterString("EQ", "AB"), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@validation()
|
||||||
|
public get Gain(): number {
|
||||||
|
return this.getParamValueNumber(this.buildParameterString("Gain"))[1];
|
||||||
|
}
|
||||||
|
public set Gain(v: number) {
|
||||||
|
this.setParamValueNumber(this.buildParameterString("Gain"), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
control: Control,
|
||||||
|
public id: number
|
||||||
|
) {
|
||||||
|
// control.validation();
|
||||||
|
super(control, "Bus", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize(): void {
|
||||||
|
console.log("Nothing to initialize");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
import { Remote } from "./Remote";
|
import { Remote } from "./Remote";
|
||||||
import { validation } from "./decorators/validation";
|
import { validation } from "../decorators/validation";
|
||||||
|
import { Device } from "./Device";
|
||||||
|
import { throwError } from "../utils/Error";
|
||||||
|
import { logger } from "../Logger";
|
||||||
|
|
||||||
export enum LoginReturnType {
|
export enum LoginReturnType {
|
||||||
"OK" = 0,
|
"OK" = 0,
|
||||||
|
@ -16,15 +19,45 @@ export enum VoicemeeterType {
|
||||||
|
|
||||||
export class Control extends Remote {
|
export class Control extends Remote {
|
||||||
private static buses = {
|
private static buses = {
|
||||||
Potato: { total: 8, virtual: 3, physical: 5 },
|
Potato: { virtual: 3, physical: 5 },
|
||||||
Banana: { total: 5, virtual: 2, physical: 3 },
|
Banana: { virtual: 2, physical: 3 },
|
||||||
Basic: { total: 2, virtual: 1, physical: 1 },
|
Basic: { virtual: 1, physical: 1 },
|
||||||
};
|
};
|
||||||
private static strips = {
|
private static strips = {
|
||||||
Potato: { total: 8, virtual: 3, physical: 5 },
|
Potato: { virtual: 3, physical: 5 },
|
||||||
Banana: { total: 8, virtual: 3, physical: 5 },
|
Banana: { virtual: 2, physical: 3 },
|
||||||
Basic: { total: 8, virtual: 3, physical: 5 },
|
Basic: { virtual: 1, physical: 2 },
|
||||||
};
|
};
|
||||||
|
private static totalBuses = (() => {
|
||||||
|
const totalBuses = {} as (typeof Control)["totalBuses"];
|
||||||
|
for (const voicemeeterVersion in Control.buses) {
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(Control.buses, voicemeeterVersion)
|
||||||
|
) {
|
||||||
|
const element =
|
||||||
|
Control.buses[voicemeeterVersion as keyof (typeof Control)["buses"]];
|
||||||
|
totalBuses[voicemeeterVersion as keyof (typeof Control)["buses"]] =
|
||||||
|
element.physical + element.virtual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalBuses;
|
||||||
|
})() as Record<keyof (typeof Control)["buses"], number>;
|
||||||
|
private static totalStrips = (() => {
|
||||||
|
const totalStrips = {} as (typeof Control)["totalStrips"];
|
||||||
|
for (const voicemeeterVersion in Control.strips) {
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(Control.strips, voicemeeterVersion)
|
||||||
|
) {
|
||||||
|
const element =
|
||||||
|
Control.strips[
|
||||||
|
voicemeeterVersion as keyof (typeof Control)["strips"]
|
||||||
|
];
|
||||||
|
totalStrips[voicemeeterVersion as keyof (typeof Control)["strips"]] =
|
||||||
|
element.physical + element.virtual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalStrips;
|
||||||
|
})() as Record<keyof (typeof Control)["strips"], number>;
|
||||||
|
|
||||||
public loggedIn: boolean = false;
|
public loggedIn: boolean = false;
|
||||||
public parametersUpdated: boolean = false;
|
public parametersUpdated: boolean = false;
|
||||||
|
@ -52,20 +85,55 @@ export class Control extends Remote {
|
||||||
|
|
||||||
@validation()
|
@validation()
|
||||||
public get availableBuses() {
|
public get availableBuses() {
|
||||||
return Control.buses[
|
return {
|
||||||
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
total:
|
||||||
];
|
Control.totalBuses[
|
||||||
|
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
||||||
|
],
|
||||||
|
...Control.buses[
|
||||||
|
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@validation()
|
@validation()
|
||||||
public get availableStrips() {
|
public get availableStrips() {
|
||||||
return Control.strips[
|
return {
|
||||||
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
total:
|
||||||
];
|
Control.totalStrips[
|
||||||
|
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
||||||
|
],
|
||||||
|
...Control.strips[
|
||||||
|
VoicemeeterType[this.voicemeeterType] as keyof typeof VoicemeeterType
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public minVersion(minVersion: number) {
|
@validation()
|
||||||
if (minVersion > this.voicemeeterType) throw new Error("Test");
|
public get availableInputDevices(): Device[] {
|
||||||
|
const numberOfDevices: number = this.run("VBVMR_Input_GetDeviceNumber");
|
||||||
|
const devices: Device[] = [];
|
||||||
|
for (let i = 0; i < numberOfDevices; i++) {
|
||||||
|
let type, deviceName, hardwareId;
|
||||||
|
const result = this.run(
|
||||||
|
"VBVMR_Input_GetDeviceDescA",
|
||||||
|
i,
|
||||||
|
type,
|
||||||
|
deviceName,
|
||||||
|
hardwareId
|
||||||
|
);
|
||||||
|
logger.log({}, type, deviceName, hardwareId);
|
||||||
|
|
||||||
|
if (result !== 0) throwError("Error happened on VM side");
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
@validation()
|
||||||
|
public get availableOutputDevices(): Device[] {
|
||||||
|
const numberOfDevices: number = this.run("VBVMR_Output_GetDeviceNumber");
|
||||||
|
const devices: Device[] = [];
|
||||||
|
for (let i = 0; i < numberOfDevices; i++) {}
|
||||||
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public login() {
|
public login() {
|
||||||
|
@ -74,7 +142,7 @@ export class Control extends Remote {
|
||||||
this.interval = setInterval(() => {
|
this.interval = setInterval(() => {
|
||||||
const result = this.run("VBVMR_IsParametersDirty");
|
const result = this.run("VBVMR_IsParametersDirty");
|
||||||
if (result !== 0 && result !== 1)
|
if (result !== 0 && result !== 1)
|
||||||
throw new Error(
|
throwError(
|
||||||
`An error occurred while checking for updated parameters. DLL result code: ${result}`
|
`An error occurred while checking for updated parameters. DLL result code: ${result}`
|
||||||
);
|
);
|
||||||
const isUpdated = result === 1 ? true : false;
|
const isUpdated = result === 1 ? true : false;
|
||||||
|
@ -89,7 +157,7 @@ export class Control extends Remote {
|
||||||
createTimer();
|
createTimer();
|
||||||
}
|
}
|
||||||
const result = this.run("VBVMR_Login") as LoginReturnType;
|
const result = this.run("VBVMR_Login") as LoginReturnType;
|
||||||
if (result !== 0) throw new Error(`DLL result code: ${result}`);
|
if (result !== 0) throwError(`DLL result code: ${result}`);
|
||||||
this.loggedIn = true;
|
this.loggedIn = true;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -102,7 +170,7 @@ export class Control extends Remote {
|
||||||
this.interval = undefined;
|
this.interval = undefined;
|
||||||
}
|
}
|
||||||
const result = this.run("VBVMR_Logout") as number;
|
const result = this.run("VBVMR_Logout") as number;
|
||||||
if (result !== 0) throw new Error(`DLL result code: ${result}`);
|
if (result !== 0) throwError(`DLL result code: ${result}`);
|
||||||
this.loggedIn = false;
|
this.loggedIn = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
9
src/VMR/Device.ts
Normal file
9
src/VMR/Device.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export type DeviceDriver = "ASIO" | "MME" | "WDM" | "KS";
|
||||||
|
|
||||||
|
export class Device {
|
||||||
|
constructor(
|
||||||
|
public driver: DeviceDriver,
|
||||||
|
public isInput: boolean,
|
||||||
|
public name: string
|
||||||
|
) {}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { IKoffiLib, KoffiFunction, load } from "koffi";
|
import { IKoffiLib, KoffiFunction, load } from "koffi";
|
||||||
import { Parser } from "../utils/getFuncsNamesFromVRHFile";
|
import { Parser } from "../utils/getFuncsNamesFromVRHFile";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import { throwError } from "../utils/Error";
|
||||||
|
|
||||||
export type RemoteFuncs = (typeof Remote.allowedFuncs)[number];
|
export type RemoteFuncs = (typeof Remote.allowedFuncs)[number];
|
||||||
|
|
||||||
|
@ -17,7 +18,9 @@ export class Remote {
|
||||||
"VBVMR_GetParameterStringA",
|
"VBVMR_GetParameterStringA",
|
||||||
"VBVMR_Output_GetDeviceNumber",
|
"VBVMR_Output_GetDeviceNumber",
|
||||||
"VBVMR_Input_GetDeviceNumber",
|
"VBVMR_Input_GetDeviceNumber",
|
||||||
"VBVMR_GetVoicemeeterVersion"
|
"VBVMR_GetVoicemeeterVersion",
|
||||||
|
"VBVMR_Input_GetDeviceDescA",
|
||||||
|
"VBVMR_Output_GetDeviceDescA"
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
public dllFuncs = {} as Partial<
|
public dllFuncs = {} as Partial<
|
||||||
|
@ -35,7 +38,7 @@ export class Remote {
|
||||||
for (const func of Remote.allowedFuncs) {
|
for (const func of Remote.allowedFuncs) {
|
||||||
const funcHeader = results.find((r) => r.name === func);
|
const funcHeader = results.find((r) => r.name === func);
|
||||||
if (funcHeader === undefined)
|
if (funcHeader === undefined)
|
||||||
throw new Error(`Allowed function not found in header file. Caused by function: ${func}`);
|
return throwError(`Allowed function not found in header file. Caused by function: ${func}`);
|
||||||
this.dllFuncs[func] = this.dll.func(funcHeader.rawString);
|
this.dllFuncs[func] = this.dll.func(funcHeader.rawString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,9 +48,9 @@ export class Remote {
|
||||||
...args: any
|
...args: any
|
||||||
) {
|
) {
|
||||||
if (!Remote.allowedFuncs.includes(command))
|
if (!Remote.allowedFuncs.includes(command))
|
||||||
throw new Error("Used function isn't listed in allowed");
|
throwError("Used function isn't listed in allowed");
|
||||||
const func = this.dllFuncs[command];
|
const func = this.dllFuncs[command];
|
||||||
if(func === undefined) throw new Error("Executed function wasn't initialized");
|
if(func === undefined)return throwError("Executed function wasn't initialized");
|
||||||
return func(...args)
|
return func(...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { VMObject } from "./VMObject";
|
import { VMObject } from "./VMObject";
|
||||||
import { minType } from "./decorators/minVersion";
|
import { minType } from "../decorators/minVersion";
|
||||||
import { validation } from "./decorators/validation";
|
import { validation } from "../decorators/validation";
|
||||||
import { Control } from "./Control";
|
import { Control } from "./Control";
|
||||||
|
|
||||||
export type OutputBuses = Record<"A" | "B", Record<number, boolean>>;
|
export type OutputBuses = Record<"A" | "B", Record<number, boolean>>;
|
||||||
|
@ -8,9 +8,7 @@ export type OutputBuses = Record<"A" | "B", Record<number, boolean>>;
|
||||||
export class Strip extends VMObject {
|
export class Strip extends VMObject {
|
||||||
@validation()
|
@validation()
|
||||||
public get Mono(): boolean {
|
public get Mono(): boolean {
|
||||||
return this.getParamValueBoolean(
|
return this.getParamValueBoolean(this.buildParameterString("Mono"))[1];
|
||||||
this.buildParameterString("Mono")
|
|
||||||
)[1];
|
|
||||||
}
|
}
|
||||||
public set Mono(v: boolean) {
|
public set Mono(v: boolean) {
|
||||||
this.setParamValueBoolean(this.buildParameterString("Mono"), v);
|
this.setParamValueBoolean(this.buildParameterString("Mono"), v);
|
||||||
|
@ -18,9 +16,7 @@ export class Strip extends VMObject {
|
||||||
|
|
||||||
@validation()
|
@validation()
|
||||||
public get Mute(): boolean {
|
public get Mute(): boolean {
|
||||||
return this.getParamValueBoolean(
|
return this.getParamValueBoolean(this.buildParameterString("Mute"))[1];
|
||||||
this.buildParameterString("Mute")
|
|
||||||
)[1];
|
|
||||||
}
|
}
|
||||||
public set Mute(v: boolean) {
|
public set Mute(v: boolean) {
|
||||||
this.setParamValueBoolean(this.buildParameterString("Mute"), v);
|
this.setParamValueBoolean(this.buildParameterString("Mute"), v);
|
||||||
|
@ -28,11 +24,9 @@ export class Strip extends VMObject {
|
||||||
|
|
||||||
@validation()
|
@validation()
|
||||||
public get Solo(): boolean {
|
public get Solo(): boolean {
|
||||||
return this.getParamValueBoolean(
|
return this.getParamValueBoolean(this.buildParameterString("Solo"))[1];
|
||||||
this.buildParameterString("Solo")
|
|
||||||
)[1];
|
|
||||||
}
|
}
|
||||||
public set Solor(v: boolean) {
|
public set Solo(v: boolean) {
|
||||||
this.setParamValueBoolean(this.buildParameterString("Solo"), v);
|
this.setParamValueBoolean(this.buildParameterString("Solo"), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +51,7 @@ export class Strip extends VMObject {
|
||||||
const buses: number[] = [];
|
const buses: number[] = [];
|
||||||
for (let i = 0; i < this.control.availableBuses.total; i++) {
|
for (let i = 0; i < this.control.availableBuses.total; i++) {
|
||||||
buses.push(
|
buses.push(
|
||||||
this.getParamValueNumber(
|
this.getParamValueNumber(this.buildParameterString("GainLayer", i))[1]
|
||||||
this.buildParameterString("GainLayer", i)
|
|
||||||
)[1]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return buses;
|
return buses;
|
||||||
|
@ -68,9 +60,7 @@ export class Strip extends VMObject {
|
||||||
let script = "";
|
let script = "";
|
||||||
for (let i = 0; i < changedBuses.length; i++) {
|
for (let i = 0; i < changedBuses.length; i++) {
|
||||||
const gainForBus = changedBuses[i];
|
const gainForBus = changedBuses[i];
|
||||||
script += `${this.buildParameterString(
|
script += `${this.buildParameterString("GainLayer", i)} = ${gainForBus};`;
|
||||||
"GainLayer", i,
|
|
||||||
)} = ${gainForBus};`;
|
|
||||||
}
|
}
|
||||||
this.setParameters(script);
|
this.setParameters(script);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +103,10 @@ export class Strip extends VMObject {
|
||||||
this.setParameters(script);
|
this.setParameters(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(control: Control, public id: number) {
|
constructor(
|
||||||
|
control: Control,
|
||||||
|
public id: number
|
||||||
|
) {
|
||||||
// control.validation();
|
// control.validation();
|
||||||
super(control, "Strip", id);
|
super(control, "Strip", id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { validate } from "./validation";
|
import { validate } from "./validation";
|
||||||
import { Control, VoicemeeterType } from "../Control";
|
import { Control, VoicemeeterType } from "../VMR/Control";
|
||||||
|
import { throwError } from "../utils/Error";
|
||||||
|
|
||||||
export function minType(minType: VoicemeeterType) {
|
export function minType(minType: VoicemeeterType) {
|
||||||
return (object: any, name: string, descriptor: PropertyDescriptor) => {
|
return (object: any, name: string, descriptor: PropertyDescriptor) => {
|
||||||
|
@ -10,7 +11,7 @@ export function minType(minType: VoicemeeterType) {
|
||||||
descriptor[key] = function (this: Control, ...args: any[]) {
|
descriptor[key] = function (this: Control, ...args: any[]) {
|
||||||
validate.bind(this)();
|
validate.bind(this)();
|
||||||
if (this.voicemeeterType < minType)
|
if (this.voicemeeterType < minType)
|
||||||
throw new Error(
|
return throwError(
|
||||||
`Used property/method with name: ${name} is not supported by this type of Voicemeeter. Your type: ${
|
`Used property/method with name: ${name} is not supported by this type of Voicemeeter. Your type: ${
|
||||||
VoicemeeterType[this.voicemeeterType]
|
VoicemeeterType[this.voicemeeterType]
|
||||||
} Minimal required type is ${VoicemeeterType[minType]}`
|
} Minimal required type is ${VoicemeeterType[minType]}`
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Control } from "../Control";
|
import { Control } from "../VMR/Control";
|
||||||
import { Strip } from "../Strip";
|
import { Strip } from "../VMR/Strip";
|
||||||
|
import { throwError } from "../utils/Error";
|
||||||
|
|
||||||
type validateThisType = Control | Strip;
|
type validateThisType = Control | Strip;
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ export function validate(this: validateThisType) {
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
if (this instanceof Control && !this.loggedIn) isValid = false;
|
if (this instanceof Control && !this.loggedIn) isValid = false;
|
||||||
else if (this instanceof Strip && !this.control.loggedIn) isValid = false;
|
else if (this instanceof Strip && !this.control.loggedIn) isValid = false;
|
||||||
if (!isValid) throw new Error("Communication pipe isn't open");
|
if (!isValid) return throwError("Communication pipe isn't open");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validation() {
|
export function validation() {
|
||||||
|
|
19
src/main.ts
19
src/main.ts
|
@ -1,14 +1,17 @@
|
||||||
import { Control, VoicemeeterType } from "./VMR/Control";
|
import { Control, VoicemeeterType } from "./VMR/Control";
|
||||||
import { Logger } from "./Logger";
|
import { logger, Logger } from "./Logger";
|
||||||
|
import { VOICEMEETER_REMOTE_DLL } from "./variables";
|
||||||
|
import { throwError } from "./utils/Error";
|
||||||
|
|
||||||
let control: Control;
|
if (VOICEMEETER_REMOTE_DLL === undefined)
|
||||||
|
throwError("The path for VM Remote dll is not specified");
|
||||||
|
let control: Control = new Control(VOICEMEETER_REMOTE_DLL!);
|
||||||
let interval: NodeJS.Timeout;
|
let interval: NodeJS.Timeout;
|
||||||
const logger = new Logger({});
|
|
||||||
|
|
||||||
function exit() {
|
function exit(eventName: (typeof exitEvents)[0]) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
control.logout();
|
if (control !== undefined && control.loggedIn) control.logout();
|
||||||
logger.log("Logout");
|
logger.log({ tag: `Signal: ${eventName.name}` }, "Logout");
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +22,12 @@ const exitEvents = [
|
||||||
{ name: "SIGUSR1" },
|
{ name: "SIGUSR1" },
|
||||||
{ name: "SIGUSR2" },
|
{ name: "SIGUSR2" },
|
||||||
{ name: "beforeExit" },
|
{ name: "beforeExit" },
|
||||||
{ name: "exit" },
|
|
||||||
{ name: "uncaughtException" },
|
{ name: "uncaughtException" },
|
||||||
{ name: "unhandledRejection" },
|
{ name: "unhandledRejection" },
|
||||||
] as { name: NodeJS.Signals }[];
|
] as { name: NodeJS.Signals }[];
|
||||||
|
|
||||||
for (const event of exitEvents) {
|
for (const event of exitEvents) {
|
||||||
process.on(event.name, exit.bind(null));
|
process.on(event.name, () => exit(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.log({}, control.availableInputDevices);
|
||||||
|
|
8
src/utils/Error.ts
Normal file
8
src/utils/Error.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { logger, Logger } from "../Logger";
|
||||||
|
import { DEBUG } from "../variables";
|
||||||
|
|
||||||
|
export function throwError(message: string) {
|
||||||
|
logger.error({ tag: "CRIT" }, message);
|
||||||
|
if (DEBUG) throw new Error(message);
|
||||||
|
process.exit(-1);
|
||||||
|
}
|
|
@ -1,7 +1,13 @@
|
||||||
export function getEnvVariable(
|
import { logger } from "../Logger";
|
||||||
name: string,
|
|
||||||
type?: "string" | "boolean" | "number"
|
export type EnvironmentVariableType = "string" | "boolean" | "number";
|
||||||
) {
|
|
||||||
|
function getEnvVariable(name: string, type: "string"): string | undefined;
|
||||||
|
function getEnvVariable(name: string, type: "boolean"): boolean | undefined;
|
||||||
|
function getEnvVariable(name: string, type: "number"): number | undefined;
|
||||||
|
function getEnvVariable(name: string, type: undefined): any | undefined;
|
||||||
|
|
||||||
|
function getEnvVariable(name: string, type?: EnvironmentVariableType) {
|
||||||
const variable = process.env[name];
|
const variable = process.env[name];
|
||||||
if (process.env[name] === undefined) return undefined;
|
if (process.env[name] === undefined) return undefined;
|
||||||
if (type === undefined) return variable;
|
if (type === undefined) return variable;
|
||||||
|
@ -9,3 +15,5 @@ export function getEnvVariable(
|
||||||
else if (type === "string") return variable;
|
else if (type === "string") return variable;
|
||||||
else if (type === "number") return new Number(variable).valueOf();
|
else if (type === "number") return new Number(variable).valueOf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { getEnvVariable };
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getEnvVariable } from "./utils/getEnvVariable";
|
import { getEnvVariable } from "./utils/getEnvVariable";
|
||||||
|
|
||||||
export const DEBUG = getEnvVariable("DEBUG", "boolean");
|
export const DEBUG = getEnvVariable("NODE_ENV", "string") !== "production";
|
||||||
export const VOICEMEETER_REMOTE_DLL = getEnvVariable(
|
export const VOICEMEETER_REMOTE_DLL = getEnvVariable(
|
||||||
"VOICEMEETER_REMOTE_DLL",
|
"VOICEMEETER_REMOTE_DLL",
|
||||||
"string"
|
"string"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user