diff --git a/client/assets/css/ReductionMeter.css b/client/assets/css/ReductionMeter.css new file mode 100644 index 00000000..745ac695 --- /dev/null +++ b/client/assets/css/ReductionMeter.css @@ -0,0 +1,36 @@ +.reductionmeter-body { + position: relative; + top: 15px; + width: 24px; + margin-top: 15px; + margin-left: 5px; + background-color: black; + border-radius: 7px; +} + +.reductionmeter-canvas { + position: absolute; + width: 10px; + margin-left: -5px; + bottom: 0; + height: 100%; +} + +.reductionmeter-lower-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(0, 122, 37); +} +.reductionmeter-middle-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(53, 167, 0); +} +.reductionmeter-upper-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(206, 0, 0); +} diff --git a/client/components/ChanStrip.tsx b/client/components/ChanStrip.tsx index a1934630..1bce3cde 100644 --- a/client/components/ChanStrip.tsx +++ b/client/components/ChanStrip.tsx @@ -21,6 +21,7 @@ import { SOCKET_SET_AUX_LEVEL } from '../../server/constants/SOCKET_IO_DISPATCHERS'; import CcgChannelInputSettings from './CcgChannelSettings'; +import ReductionMeter from './ReductionMeter'; interface IChanStripInjectProps { label: string, @@ -195,6 +196,14 @@ class ChanStrip extends React.PureComponent + Gain Red. + + + ) + } delay() { return ( @@ -383,6 +392,7 @@ class ChanStrip extends React.PureComponent______

{this.ratio()}

______

+ {this.gainReduction()}

{this.delay()} diff --git a/client/components/ReductionMeter.tsx b/client/components/ReductionMeter.tsx new file mode 100644 index 00000000..f5409b6f --- /dev/null +++ b/client/components/ReductionMeter.tsx @@ -0,0 +1,170 @@ +import * as React from 'react' +import { connect } from "react-redux" + +//assets: +import '../assets/css/ReductionMeter.css' +//Utils: + +export interface IReductionMeterInjectedProps { + reductionVal: number +} + +interface IVuMeterProps { + faderIndex: number +} + +export class ReductionMeter extends React.Component { + canvas: HTMLCanvasElement | undefined + + totalPeak: number = 0 + windowPeak: number = 0 + windowLast: number = 0 + WINDOW: number = 2000 + + constructor(props: any) { + super(props) + } + + public shouldComponentUpdate(nextProps: IReductionMeterInjectedProps) { + return ( + nextProps.reductionVal != this.props.reductionVal + ) + } + + totalHeight = () => { + return 170 / (window.mixerProtocol.meter.max - window.mixerProtocol.meter.min) + } + + getTotalPeak = () => { + if (this.props.reductionVal > this.totalPeak) { + this.totalPeak = this.props.reductionVal + } + return this.totalHeight()*this.totalPeak + } + + getWindowPeak = () => { + if (this.props.reductionVal > this.windowPeak || (Date.now() - this.windowLast) > this.WINDOW) { + this.windowPeak = this.props.reductionVal + this.windowLast = Date.now() + } + return this.totalHeight()*this.windowPeak + } + + calcLower = () => { + let val = this.props.reductionVal + if (val >= window.mixerProtocol.meter.test) { + val = window.mixerProtocol.meter.test + } + return val + } + + calcMiddle = () => { + let val = this.props.reductionVal + if (val < window.mixerProtocol.meter.test) { + val = window.mixerProtocol.meter.test + } else if (val >= window.mixerProtocol.meter.zero) { + val = window.mixerProtocol.meter.zero + } + return val+1 + } + + calcUpper = () => { + let val = this.props.reductionVal + if (val < window.mixerProtocol.meter.zero) { + val = window.mixerProtocol.meter.zero + } + return val+1 + } + + setRef = (element: HTMLCanvasElement) => { + this.canvas = element + + this.paintVuMeter() + } + + resetTotalPeak = () => { + this.totalPeak = 0 + } + + paintVuMeter = () => { + if (!this.canvas) return + + const context = this.canvas.getContext("2d", { + antialias: false, + stencil: false, + preserveDrawingBuffer: true + }) as CanvasRenderingContext2D + + if (!context) return + + context.clearRect(0, 0, this.canvas.clientWidth, this.canvas.clientHeight) + + // lower part + context.fillStyle = 'rgb(0, 122, 37)' + context.fillRect(0, 0, this.canvas.clientWidth, this.calcLower()) //(this.totalHeight() - this.calcLower()), this.canvas.clientWidth, this.calcLower()) + + // middle part + let middle = this.calcMiddle() + let middleRef = this.totalHeight() * window.mixerProtocol.meter.test + context.fillStyle = 'rgb(53, 167, 0)' + context.fillRect(0, middleRef, this.canvas.clientWidth, middle)// (this.totalHeight() * (range - window.mixerProtocol.meter.test) - this.calcMiddle()), this.canvas.clientWidth, this.calcMiddle()) + + // upper part (too high/clip) + let upper = this.calcUpper() + let upperRef = this.totalHeight() * window.mixerProtocol.meter.zero + context.fillStyle = 'rgb(206, 0, 0)' + context.fillRect(0, upperRef, this.canvas.clientWidth, upper) + + // windowed peak + const windowPeak = this.getWindowPeak() + if (this.windowPeak < window.mixerProtocol.meter.zero) { + context.fillStyle = 'rgb(16, 56, 0)' + } else { + context.fillStyle = 'rgb(100, 100, 100)' + } + context.fillRect(0, (this.totalHeight() - windowPeak), this.canvas.clientWidth, 2) + + // absolute peak + if (this.totalPeak < window.mixerProtocol.meter.zero) { + context.fillStyle = 'rgb(64, 64, 64)' + } else { + context.fillStyle = 'rgb(255, 0, 0)' + } + context.fillRect(0, (this.totalHeight() - this.getTotalPeak()), this.canvas.clientWidth, 2) + } + + render() { + this.paintVuMeter() + + return ( +
+ + +
+ ) + } +} + +const mapStateToProps = (state: any, props: any): IReductionMeterInjectedProps => { + return { + reductionVal: state.faders[0].vuMeters[props.faderIndex].reductionVal + } +} + +export default connect(mapStateToProps)(ReductionMeter) diff --git a/client/utils/SocketClientHandlers.ts b/client/utils/SocketClientHandlers.ts index dcb751ec..fe637234 100644 --- a/client/utils/SocketClientHandlers.ts +++ b/client/utils/SocketClientHandlers.ts @@ -1,7 +1,7 @@ -import { SET_COMPLETE_FADER_STATE, SET_VU_LEVEL, SET_SINGLE_FADER_STATE } from "../../server/reducers/faderActions"; +import { SET_COMPLETE_FADER_STATE, SET_VU_LEVEL, SET_SINGLE_FADER_STATE, SET_VU_REDUCTION_LEVEL } from "../../server/reducers/faderActions"; import { SET_COMPLETE_CH_STATE, SET_SINGLE_CH_STATE } from "../../server/reducers/channelActions"; import { UPDATE_SETTINGS, SET_MIXER_ONLINE, SET_SERVER_ONLINE } from "../../server/reducers/settingsActions"; -import { SOCKET_SET_VU, SOCKET_RETURN_SNAPSHOT_LIST, SOCKET_SET_FULL_STORE, SOCKET_SET_STORE_FADER, SOCKET_SET_STORE_CHANNEL, SOCKET_RETURN_CCG_LIST } from "../../server/constants/SOCKET_IO_DISPATCHERS"; +import { SOCKET_SET_VU, SOCKET_RETURN_SNAPSHOT_LIST, SOCKET_SET_FULL_STORE, SOCKET_SET_STORE_FADER, SOCKET_SET_STORE_CHANNEL, SOCKET_RETURN_CCG_LIST, SOCKET_SET_VU_REDUCTION } from "../../server/constants/SOCKET_IO_DISPATCHERS"; export const socketClientHandlers = () => { window.socketIoClient @@ -98,6 +98,15 @@ export const socketClientHandlers = () => { }); }) ) + .on(SOCKET_SET_VU_REDUCTION, ( + (payload: any) => { + window.storeRedux.dispatch({ + type:SET_VU_REDUCTION_LEVEL, + channel: payload.faderIndex, + level: payload.level + }); + }) + ) .on(SOCKET_RETURN_SNAPSHOT_LIST, ( (payload: any) => { window.snapshotFileList = payload diff --git a/server/constants/MixerProtocolInterface.ts b/server/constants/MixerProtocolInterface.ts index 5c8c77eb..2fad99f5 100644 --- a/server/constants/MixerProtocolInterface.ts +++ b/server/constants/MixerProtocolInterface.ts @@ -32,6 +32,7 @@ export interface IChannelTypes { fromMixer: { CHANNEL_OUT_GAIN: Array, CHANNEL_VU: Array, + CHANNEL_VU_REDUCTION: Array, CHANNEL_NAME: Array PFL: Array NEXT_SEND: Array diff --git a/server/constants/SOCKET_IO_DISPATCHERS.ts b/server/constants/SOCKET_IO_DISPATCHERS.ts index 2ac1ef65..a2614be3 100644 --- a/server/constants/SOCKET_IO_DISPATCHERS.ts +++ b/server/constants/SOCKET_IO_DISPATCHERS.ts @@ -28,6 +28,7 @@ export const SOCKET_CLEAR_PST = 'clearPst' export const SOCKET_SAVE_SETTINGS = 'saveSettings' export const SOCKET_RESTART_SERVER = 'restartServer' export const SOCKET_SET_VU = 'setVu' +export const SOCKET_SET_VU_REDUCTION = 'setVuReduction' export const SOCKET_GET_SNAPSHOT_LIST = 'getSnapshotList' export const SOCKET_RETURN_SNAPSHOT_LIST = 'returnSnapshotList' export const SOCKET_GET_CCG_LIST = 'getCcgList' diff --git a/server/constants/mixerProtocols/DmxIs.ts b/server/constants/mixerProtocols/DmxIs.ts index d5517ee0..285b3382 100644 --- a/server/constants/mixerProtocols/DmxIs.ts +++ b/server/constants/mixerProtocols/DmxIs.ts @@ -16,6 +16,7 @@ export const DMXIS: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: '/dmxis/ch/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/LawoMC2.ts b/server/constants/mixerProtocols/LawoMC2.ts index 759cb12f..9e23e8dc 100644 --- a/server/constants/mixerProtocols/LawoMC2.ts +++ b/server/constants/mixerProtocols/LawoMC2.ts @@ -23,6 +23,7 @@ export const LawoMC2: IMixerProtocol = { zero: 0 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: '', value: 0, diff --git a/server/constants/mixerProtocols/LawoRelayVrx4.ts b/server/constants/mixerProtocols/LawoRelayVrx4.ts index 3a60aa62..50e67330 100644 --- a/server/constants/mixerProtocols/LawoRelayVrx4.ts +++ b/server/constants/mixerProtocols/LawoRelayVrx4.ts @@ -23,6 +23,7 @@ export const LawoRelayVrx4: IMixerProtocol = { zero: 75 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: '', value: 0, diff --git a/server/constants/mixerProtocols/LawoRuby.ts b/server/constants/mixerProtocols/LawoRuby.ts index 2333a419..96a0b024 100644 --- a/server/constants/mixerProtocols/LawoRuby.ts +++ b/server/constants/mixerProtocols/LawoRuby.ts @@ -23,6 +23,7 @@ export const LawoRuby: IMixerProtocol = { zero: 0 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: '', value: 0, diff --git a/server/constants/mixerProtocols/SSLsystemT.ts b/server/constants/mixerProtocols/SSLsystemT.ts index 4e33559e..cad99ac7 100644 --- a/server/constants/mixerProtocols/SSLsystemT.ts +++ b/server/constants/mixerProtocols/SSLsystemT.ts @@ -16,6 +16,7 @@ export const SSLSystemT: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [emptyMixerMessage()], // Handled by SSLMixerconnection CHANNEL_VU: [emptyMixerMessage()], // Not implemented in SSL Automation protocol yet + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/StuderOnAirEmber.ts b/server/constants/mixerProtocols/StuderOnAirEmber.ts index e944d461..0b49ed15 100644 --- a/server/constants/mixerProtocols/StuderOnAirEmber.ts +++ b/server/constants/mixerProtocols/StuderOnAirEmber.ts @@ -23,6 +23,7 @@ export const StuderOnAirMaster: IMixerProtocol = { zero: 0 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', value: 0, diff --git a/server/constants/mixerProtocols/StuderVistaEmber.ts b/server/constants/mixerProtocols/StuderVistaEmber.ts index d6b53a31..9671286f 100644 --- a/server/constants/mixerProtocols/StuderVistaEmber.ts +++ b/server/constants/mixerProtocols/StuderVistaEmber.ts @@ -16,6 +16,7 @@ export const StuderVistaMaster: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [emptyMixerMessage()], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], @@ -76,6 +77,7 @@ export const StuderVistaMaster: IMixerProtocol = { zero: 750 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Channel Attribute/User Label', value: 0, @@ -143,6 +145,7 @@ export const StuderVistaMaster: IMixerProtocol = { zero: 750 }], CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Channel Attribute/User Label', value: 0, diff --git a/server/constants/mixerProtocols/ardourMaster.ts b/server/constants/mixerProtocols/ardourMaster.ts index fc441290..f680f363 100644 --- a/server/constants/mixerProtocols/ardourMaster.ts +++ b/server/constants/mixerProtocols/ardourMaster.ts @@ -43,6 +43,7 @@ export const ArdourMaster: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: '/strip/fader/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], CHANNEL_VU: [{ mixerMessage: '/strip/meter/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: '/strip/name/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/behringerXrMaster.ts b/server/constants/mixerProtocols/behringerXrMaster.ts index babefecb..0b1db67c 100644 --- a/server/constants/mixerProtocols/behringerXrMaster.ts +++ b/server/constants/mixerProtocols/behringerXrMaster.ts @@ -38,6 +38,7 @@ export const BehringerXrMaster: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], CHANNEL_VU: [{ mixerMessage: '/meters/1', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], + CHANNEL_VU_REDUCTION: [{ mixerMessage: '/meters/1', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], CHANNEL_NAME: [{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/casparCGMaster.ts b/server/constants/mixerProtocols/casparCGMaster.ts index 9b22f3e0..f6989e78 100644 --- a/server/constants/mixerProtocols/casparCGMaster.ts +++ b/server/constants/mixerProtocols/casparCGMaster.ts @@ -122,7 +122,8 @@ let CasparCGMasterObject: ICasparCGMixerGeometry = { channelTypeColor: '#2f2f2f', fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: 'none', value: 0, type: 'f', min: 0, max: 1.5, zero: 1}], - CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/genericMidi.ts b/server/constants/mixerProtocols/genericMidi.ts index ac739619..7525135f 100644 --- a/server/constants/mixerProtocols/genericMidi.ts +++ b/server/constants/mixerProtocols/genericMidi.ts @@ -16,6 +16,7 @@ export const GenericMidi: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command CHANNEL_VU: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/midasMaster.ts b/server/constants/mixerProtocols/midasMaster.ts index 60a6fc0c..a6ccdb30 100644 --- a/server/constants/mixerProtocols/midasMaster.ts +++ b/server/constants/mixerProtocols/midasMaster.ts @@ -120,6 +120,7 @@ export const MidasMaster: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], CHANNEL_VU: [{ mixerMessage: '/meters/1', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], //[{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/reaperMaster.ts b/server/constants/mixerProtocols/reaperMaster.ts index d54ac809..3ca32a07 100644 --- a/server/constants/mixerProtocols/reaperMaster.ts +++ b/server/constants/mixerProtocols/reaperMaster.ts @@ -16,6 +16,7 @@ export const ReaperMaster: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: '/track/{channel}/volume', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], CHANNEL_VU: [{ mixerMessage: '/track/{channel}/vu', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [{ mixerMessage: '/track/{channel}/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], @@ -71,6 +72,7 @@ export const ReaperMaster: IMixerProtocol = { { mixerMessage: '/master/vu/L', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }, { mixerMessage: '/master/vu/R', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 } ], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/constants/mixerProtocols/yamahaQLCL.ts b/server/constants/mixerProtocols/yamahaQLCL.ts index c3ccf732..47436632 100644 --- a/server/constants/mixerProtocols/yamahaQLCL.ts +++ b/server/constants/mixerProtocols/yamahaQLCL.ts @@ -25,6 +25,7 @@ export const YamahaQLCL: IMixerProtocol = { fromMixer: { CHANNEL_OUT_GAIN: [{ mixerMessage: 'f0 43 10 3e 19 01 00 37 00 00 {channel} 00 00 00 {level} f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command CHANNEL_VU: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], CHANNEL_NAME: [emptyMixerMessage()], PFL: [emptyMixerMessage()], NEXT_SEND: [emptyMixerMessage()], diff --git a/server/reducers/faderActions.ts b/server/reducers/faderActions.ts index 7b458014..b52a0fcd 100644 --- a/server/reducers/faderActions.ts +++ b/server/reducers/faderActions.ts @@ -1,4 +1,5 @@ export const SET_VU_LEVEL = 'SET_VU_LEVEL' +export const SET_VU_REDUCTION_LEVEL = 'SET_REDUCTION_LEVEL' export const SET_COMPLETE_FADER_STATE = 'SET_COMPLETE_FADER_STATE' export const SET_SINGLE_FADER_STATE = 'SET_SINGLE_FADER_STATE' export const SET_FADER_LEVEL = 'SET_FADER_LEVEL' diff --git a/server/reducers/fadersReducer.ts b/server/reducers/fadersReducer.ts index 49fbbc7d..ebdf88ad 100644 --- a/server/reducers/fadersReducer.ts +++ b/server/reducers/fadersReducer.ts @@ -15,6 +15,7 @@ import { TOGGLE_SNAP, SET_VO, SET_VU_LEVEL, + SET_VU_REDUCTION_LEVEL, SHOW_CHANNEL, IGNORE_AUTOMATION, SNAP_RECALL, @@ -65,7 +66,8 @@ export interface IFader { } export interface IVuMeters { - vuVal: number + vuVal: number, + reductionVal: number } const defaultFadersReducerState = (numberOfFaders: number): IFaders[] => { @@ -99,7 +101,8 @@ const defaultFadersReducerState = (numberOfFaders: number): IFaders[] => { snapOn: [], }); defaultObj[0].vuMeters.push({ - vuVal: 0.0 + vuVal: 0.0, + reductionVal: 0.0, }); for (let y=0; y < DEFAULTS.NUMBER_OF_SNAPS; y++) { defaultObj[0].fader[index].snapOn.push(false); @@ -121,6 +124,11 @@ export const faders = ((state = defaultFadersReducerState(0), action: any): Arra nextState[0].vuMeters[action.channel].vuVal = parseFloat(action.level); } return nextState; + case SET_VU_REDUCTION_LEVEL: //channel: level: + if (typeof nextState[0].vuMeters[action.channel] !== 'undefined') { + nextState[0].vuMeters[action.channel].reductionVal = parseFloat(action.level); + } + return nextState; case SET_COMPLETE_FADER_STATE: //allState //numberOfChannels let emptyState = defaultFadersReducerState(action.numberOfTypeChannels) if (emptyState[0].vuMeters.length === nextState[0].vuMeters.length) { diff --git a/server/utils/mixerConnections/OscMixerConnection.ts b/server/utils/mixerConnections/OscMixerConnection.ts index 17e86975..74e2c5b9 100644 --- a/server/utils/mixerConnections/OscMixerConnection.ts +++ b/server/utils/mixerConnections/OscMixerConnection.ts @@ -7,11 +7,11 @@ import { socketServer } from '../../expressHandler' //Utils: import { IMixerProtocol } from '../../constants/MixerProtocolInterface' -import { behringerMeter } from './productSpecific/behringer' +import { behringerMeter, behringerReductionMeter } from './productSpecific/behringer' import { midasMeter } from './productSpecific/midas' import { SET_OUTPUT_LEVEL, SET_AUX_LEVEL } from '../../reducers/channelActions' import { - SET_VU_LEVEL, + SET_VU_LEVEL, SET_FADER_LEVEL, SET_CHANNEL_LABEL, TOGGLE_PGM, @@ -22,10 +22,11 @@ import { SET_FADER_HIGH, SET_FADER_LOW, SET_FADER_DELAY_TIME, - SET_MUTE + SET_MUTE, + SET_VU_REDUCTION_LEVEL } from '../../reducers/faderActions' import { SET_MIXER_ONLINE } from '../../reducers/settingsActions'; -import { SOCKET_SET_VU } from '../../constants/SOCKET_IO_DISPATCHERS'; +import { SOCKET_SET_VU, SOCKET_SET_VU_REDUCTION } from '../../constants/SOCKET_IO_DISPATCHERS'; import { logger } from '../logger' export class OscMixerConnection { @@ -75,6 +76,32 @@ export class OscMixerConnection { mixerOnline: true }); logger.verbose("Received OSC message: " + message.address, {}) +/// ONLY TEST!!!! + if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_VU_REDUCTION[0].mixerMessage)){ + if (state.settings[0].mixerProtocol.includes('behringer')) { + behringerReductionMeter(message.args); + } else if (state.settings[0].mixerProtocol.includes('midas')) { + midasMeter(message.args); + } else { + let ch = message.address.split("/")[this.cmdChannelIndex]; + store.dispatch({ + type:SET_VU_REDUCTION_LEVEL, + channel: state.channels[0].channel[ch - 1].assignedFader, + level: message.args[0] + }); + socketServer.emit( + SOCKET_SET_VU_REDUCTION, + { + faderIndex: state.channels[0].channel[ch - 1].assignedFader, + level: message.args[0] + } + ) + } + } + + + if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer .CHANNEL_VU[0].mixerMessage)){ if (state.settings[0].mixerProtocol.includes('behringer')) { @@ -96,6 +123,27 @@ export class OscMixerConnection { } ) } + } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_VU_REDUCTION[0].mixerMessage)){ + if (state.settings[0].mixerProtocol.includes('behringer')) { + behringerReductionMeter(message.args); + } else if (state.settings[0].mixerProtocol.includes('midas')) { + midasMeter(message.args); + } else { + let ch = message.address.split("/")[this.cmdChannelIndex]; + store.dispatch({ + type:SET_VU_REDUCTION_LEVEL, + channel: state.channels[0].channel[ch - 1].assignedFader, + level: message.args[0] + }); + socketServer.emit( + SOCKET_SET_VU_REDUCTION, + { + faderIndex: state.channels[0].channel[ch - 1].assignedFader, + level: message.args[0] + } + ) + } } else if ( this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer .CHANNEL_OUT_GAIN[0].mixerMessage)){ let ch = message.address.split("/")[this.cmdChannelIndex]; diff --git a/server/utils/mixerConnections/productSpecific/behringer.ts b/server/utils/mixerConnections/productSpecific/behringer.ts index 048c48a2..43db8b36 100644 --- a/server/utils/mixerConnections/productSpecific/behringer.ts +++ b/server/utils/mixerConnections/productSpecific/behringer.ts @@ -2,8 +2,8 @@ import { store, state } from '../../../reducers/store' import { socketServer } from '../../../expressHandler' import * as DEFAULTS from '../../../constants/DEFAULTS'; -import { SET_VU_LEVEL } from '../../../reducers/faderActions' -import { SOCKET_SET_VU } from '../../../constants/SOCKET_IO_DISPATCHERS'; +import { SET_VU_LEVEL, SET_VU_REDUCTION_LEVEL } from '../../../reducers/faderActions' +import { SOCKET_SET_VU, SOCKET_SET_VU_REDUCTION } from '../../../constants/SOCKET_IO_DISPATCHERS'; export const behringerMeter = (message: any) => { @@ -29,5 +29,30 @@ export const behringerMeter = (message: any) => { } ) } -}; +} + +export const behringerReductionMeter = (message: any) => { + + //Test data from Behringer: + //message = [40, 0, 0, 0, 133, 157, 183, 156, 72, 154, 101, 157, 229, 162, 241, 158, 253, 162, 156, 162, 131, 162, 253, 162, 81, 162, 29, 162, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 223, 157, 223, 157, 223, 157, 223, 157]; + + let uint8bytes = Uint8Array.from(message[0]); + let dataview = new DataView(uint8bytes.buffer); + + for (let i=0; i < state.settings[0].numberOfChannelsInType[0]; i++) { + let level = (dataview.getInt16(2*(i+2) , true) + 8000)/8000 + store.dispatch({ + type:SET_VU_REDUCTION_LEVEL, + channel: i, + level: level + }); + socketServer.emit( + SOCKET_SET_VU_REDUCTION, + { + faderIndex: state.channels[0].channel[i].assignedFader, + level: level + } + ) + } +}