Skip to content

Commit

Permalink
feat(casparcg): support VU meters on CCG mixer
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarpl committed Jun 11, 2019
1 parent 8ac7ac1 commit f6a5c4d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 22 deletions.
9 changes: 2 additions & 7 deletions src/@types/osc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ declare module 'osc' {

interface OSCMessage {
address: string,
args: TypeAnnotatedArg | TypeAnnotatedArg[]
args: any[]
}

type OSCMessageOrBundle = OSCMessage | OSCBundle
Expand All @@ -28,12 +28,6 @@ declare module 'osc' {
a: number
}

interface TypeAnnotatedArg {
type: string
value: any
}


interface OSCPort extends EventEmitter {
on(event: 'ready', handler: () => void): this
on(event: 'message', handler: (message: OSCMessage, timeTag: TimeTag | undefined, info: any) => void): this
Expand Down Expand Up @@ -64,5 +58,6 @@ declare module 'osc' {
on(event: "raw", handler: (data: Uint8Array, info: any) => void): this
on(event: "error", handler: (error: Error) => void): this
send(packet: OSCMessage | OSCBundle): void
open(): void
}
}
15 changes: 10 additions & 5 deletions src/constants/MixerProtocolPresets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,23 @@ export interface ChannelLayerPair {
export interface ICasparCGMixerGeometryFile {
label?: string,
channelLabels?: string[],
PGM_CHANNEL_FADER_LEVEL: Array<ChannelLayerPair[]>,
MONITOR_CHANNEL_FADER_LEVEL: Array<ChannelLayerPair[]>
fromMixer: {
CHANNEL_VU: Array<string[]>,
}
toMixer: {
PGM_CHANNEL_FADER_LEVEL: Array<ChannelLayerPair[]>,
MONITOR_CHANNEL_FADER_LEVEL: Array<ChannelLayerPair[]>
}
}

export interface ICasparCGMixerGeometry extends IMixerProtocolGeneric {
studio: string,
leadingZeros: boolean,
pingTime: number,
fromMixer: {
CHANNEL_FADER_LEVEL: string,
CHANNEL_OUT_GAIN: string,
CHANNEL_VU: string,
// CHANNEL_FADER_LEVEL: ChannelLayerPair[],
// CHANNEL_OUT_GAIN: ChannelLayerPair[],
CHANNEL_VU: Array<string[]>,
},
toMixer: {
PGM_CHANNEL_FADER_LEVEL: Array<ChannelLayerPair[]>,
Expand Down
10 changes: 3 additions & 7 deletions src/constants/mixerProtocols/casparCGMaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ try {
let inputObj = JSON.parse(fs.readFileSync(geometryFile, {
encoding: 'utf-8'
}))
if (inputObj.MONITOR_CHANNEL_FADER_LEVEL && inputObj.PGM_CHANNEL_FADER_LEVEL) {
if (inputObj.toMixer && inputObj.toMixer.PGM_CHANNEL_FADER_LEVEL) {
geometry = inputObj
}
} catch (e) {
Expand All @@ -29,12 +29,8 @@ if (geometry) {
studio: "rk10",
leadingZeros: false,
pingTime: 0,
fromMixer: {
CHANNEL_FADER_LEVEL: "39", //PgmChange 0 - ignores this command
CHANNEL_OUT_GAIN: "0", //PgmChange 0 - ignores this command
CHANNEL_VU: "0", //PgmChange 0 - ignores this command
},
toMixer: geometry,
fromMixer: geometry.fromMixer,
toMixer: geometry.toMixer,
fader: {
min: 0,
max: 1.5,
Expand Down
40 changes: 37 additions & 3 deletions src/utils/CasparCGConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import { IMixerProtocol, MixerProtocolPresets, ICasparCGMixerGeometry, ChannelLa
import { IStore } from '../reducers/indexReducer';
import { IChannel } from '../reducers/channelsReducer';

interface CommandChannelMap {
[key: string]: number
}

export class CasparCGConnection {
store: IStore;
mixerProtocol: ICasparCGMixerGeometry;
connection: CasparCG;
oscClient: osc.UDPPort | undefined;
oscCommandMap: { [key: string]: CommandChannelMap } = {};

constructor(mixerProtocol: ICasparCGMixerGeometry) {
this.store = window.storeRedux.getState() as IStore;
Expand All @@ -38,23 +43,44 @@ export class CasparCGConnection {
console.log("CasparCG disconnected");
}
this.connection.connect();

this.oscCommandMap.CHANNEL_VU = {}
this.mixerProtocol.fromMixer.CHANNEL_VU.forEach((paths, index) => {
this.oscCommandMap.CHANNEL_VU[paths[0]] = index
})
}

setupMixerConnection() {
if (!this.oscClient) {
const remotePort = parseInt(this.store.settings[0].devicePort + '') + 1000
this.oscClient = new osc.UDPPort({
localAddress: this.store.settings[0].localIp,
localPort: parseInt(this.store.settings[0].localOscPort + ''),
localPort: remotePort,
remoteAddress: this.store.settings[0].deviceIp,
remotePort: parseInt(this.store.settings[0].devicePort + '') + 1000
remotePort
})
.on('ready', () => {

console.log("Receiving state of mixer");
})
.on('message', (message: osc.OSCMessage) => {
const index = this.checkOscCommand(message.address, this.oscCommandMap.CHANNEL_VU)
if (index !== undefined && message.args) {
window.storeRedux.dispatch({
type: 'SET_VU_LEVEL',
channel: index,
// CCG returns "produced" audio levels, before the Volume mixer transform
// We therefore want to premultiply this to show useful information about audio levels
level: Math.min(1, message.args[0] * this.store.channels[0].channel[index].faderLevel)
});
}
})
.on('error', (error: any) => {
console.log("Error : ", error);
console.log("Lost OSC connection");
});

this.oscClient.open();
console.log("Listening for status on CasparCG: ", this.store.settings[0].deviceIp, remotePort)
}

// Restore mixer values to the ones we have internally
Expand All @@ -75,6 +101,14 @@ export class CasparCGConnection {
}
}

checkOscCommand(address: string, commandSpace: CommandChannelMap): number | undefined {
const index = commandSpace[address]
if (index !== undefined) {
return index
}
return undefined
}

pingMixerCommand = () => {
//Ping OSC mixer if mixerProtocol needs it.
/* this.mixerProtocol.pingCommand.map((command) => {
Expand Down

0 comments on commit f6a5c4d

Please sign in to comment.