Skip to content

Commit

Permalink
feat: RemoteFader support - preparing support
Browse files Browse the repository at this point in the history
  • Loading branch information
olzzon committed May 31, 2019
1 parent 7a4a838 commit 5ed8364
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import Settings from './Settings';
import { loadSnapshotState, saveSnapshotState } from '../utils/SettingsStorage';
import { MixerConnection } from '../utils/MixerConnection';
import { AutomationConnection } from '../utils/AutomationConnection';
import { MidiRemoteConnection } from '../utils/MidiRemoteConnection';


class App extends Component<any, any> {
mixerConnection: any;
automationConnection: any;
midiRemoteConnection: any;

constructor(props: any) {
super(props)
Expand All @@ -23,6 +25,7 @@ class App extends Component<any, any> {
componentWillMount() {
this.mixerConnection = new MixerConnection(this.props.store);
this.automationConnection = new AutomationConnection(this.mixerConnection);
this.midiRemoteConnection = new MidiRemoteConnection(this.mixerConnection);
this.snapShopStoreTimer();
loadSnapshotState(this.props.store.channels[0], this.props.store.settings[0].numberOfChannels);
}
Expand Down
123 changes: 123 additions & 0 deletions src/constants/RemoteFaderPresets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//While developing mixer specific settings will be in one file.
//At first release these will be in seperate files
//So it´s easy to add new equipment.

export interface IRemoteProtocol {
protocol: string,
label: string,
mode: string,
leadingZeros: boolean,
initializeCommands: [
{
oscMessage: string,
value: string,
type: string
}
],
fromRemote: {
CHANNEL_PGM_ON_OFF: string,
CHANNEL_PST_ON_OFF: string,
CHANNEL_FADER_LEVEL: string,
CHANNEL_VISIBLE: string,
GRP_FADER_PGM_ON_OFF: string,
GRP_FADER_PST_ON_OFF: string,
GRP_FADER_LEVEL: string,
GRP_FADER_VISIBLE: string,
X_MIX: string,
FADE_TO_BLACK: string,
SNAP_RECALL: string,
STATE_CHANNEL_PGM: string,
STATE_CHANNEL_PST: string,
STATE_CHANNEL_FADER_LEVEL: string,
STATE_GRP_FADER_PGM: string,
STATE_GRP_FADER_PST: string,
STATE_GRP_FADER_LEVEL: string,
},
toRemote: {
STATE_CHANNEL_PGM: string,
STATE_CHANNEL_PST: string,
STATE_CHANNEL_FADER_LEVEL: string,
STATE_GRP_FADER_PGM: string,
STATE_GRP_FADER_PST: string,
STATE_GRP_FADER_LEVEL: string,
},
fader: {
min: number,
max: number,
zero: number,
step: number,
fadeTime: number,
},
meter: {
min: number,
max: number,
zero: number,
test: number,
},
}


export const RemoteFaderPresets: { [key: string]: IRemoteProtocol } = {

hui: {
protocol: 'MIDI',
label: 'HUI Midicontroller',
mode: "client",
leadingZeros: true,
initializeCommands: [
{
oscMessage: "/info",
value: "",
type: "f"
}
],
fromRemote: {
CHANNEL_PGM_ON_OFF: '/ch/{value1}/mix/pgm',
CHANNEL_PST_ON_OFF: '/ch/{value1}/mix/pst',
CHANNEL_FADER_LEVEL: '/ch/{value1}/mix/faderlevel',
CHANNEL_VISIBLE: '/ch/{value1}/visible',
GRP_FADER_PGM_ON_OFF: '/grp/{value1}/pgm',
GRP_FADER_PST_ON_OFF: '/grp/{value1}/pst',
GRP_FADER_LEVEL: '/grp/{value1}/faderlevel',
GRP_FADER_VISIBLE: '/grp/{value1}/visible',
X_MIX: '/take',
FADE_TO_BLACK: '/fadetoblack',
SNAP_RECALL: '/snap/{value1}',
STATE_CHANNEL_PGM: '/state/ch/{value1}/mix/pgm',
STATE_CHANNEL_PST: '/state/ch/{value1}/mix/pst',
STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/mix/faderlevel',
STATE_GRP_FADER_PGM: '/state/grp/{value1}/pgm',
STATE_GRP_FADER_PST: '/state/grp/{value1}/pst',
STATE_GRP_FADER_LEVEL: '/state/grp/{value1}/faderlevel',
},
toRemote: {
STATE_CHANNEL_PGM: '/state/ch/{value1}/mix/pgm',
STATE_CHANNEL_PST: '/state/ch/{value1}/mix/pst',
STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/mix/faderlevel',
STATE_GRP_FADER_PGM: '/state/grp/{value1}/pgm',
STATE_GRP_FADER_PST: '/state/grp/{value1}/pst',
STATE_GRP_FADER_LEVEL: '/state/grp/{value1}/faderlevel',
},
fader: {
min: 0,
max: 1,
zero: 0.75,
step: 0.01,
fadeTime: 40,
},
meter: {
min: 0,
max: 1,
zero: 0.75,
test: 0.6,
},
}
};


export const RemoteFaderProtocolList = Object.getOwnPropertyNames(RemoteFaderPresets).map((preset) => {
return {
value: preset,
label: RemoteFaderPresets[preset].label
};
});
142 changes: 142 additions & 0 deletions src/utils/MidiRemoteConnection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//Node Modules:
import os from 'os'; // Used to display (log) network addresses on local machine
import WebMidi, { INoteParam, IMidiChannel } from 'webmidi';

//Utils:
import { IRemoteProtocol, RemoteFaderPresets } from '../constants/RemoteFaderPresets';

export class MidiRemoteConnection {
store: any;
mixerConnection: any;
remoteProtocol: IRemoteProtocol;
midiInput: any;
midiOutput:any;

constructor() {
this.sendOutMessage = this.sendOutMessage.bind(this);

this.store = window.storeRedux.getState();
const unsubscribe = window.storeRedux.subscribe(() => {
this.store = window.storeRedux.getState();
});

this.remoteProtocol = RemoteFaderPresets[this.store.settings[0].mixerProtocol] || RemoteFaderPresets.hui;


WebMidi.enable((err) => {

if (err) {
console.log("WebMidi could not be enabled.", err);
}

// Viewing available inputs and outputs
console.log("Midi inputs : ", WebMidi.inputs);
console.log("Midi outputs : ", WebMidi.outputs);

// Display the current time
console.log("Midi time : ", WebMidi.time);

this.midiInput = WebMidi.getInputByName("IAC-driver ProducersMixer");
this.midiOutput = WebMidi.getOutputByName("IAC-driver ProducersMixer");

this.setupMixerConnection();
});
}

setupMixerConnection() {
this.midiInput.addListener('controlchange', this.remoteProtocol.fromRemote.CHANNEL_FADER_LEVEL,
(error: any) => {
console.log("Received 'controlchange' message (" + error.data + ").");
window.storeRedux.dispatch({
type:'SET_FADER_LEVEL',
channel: error.channel - 1,
level: error.data[2]
});
if (this.store.channels[0].channel[error.channel - 1].pgmOn && this.remoteProtocol.mode === 'master')
{
this.updateOutLevel(error.channel-1);
}
}
);
this.midiInput.addListener('noteon', "all",
(error: any) => {
console.log("Received 'noteon' message (" + error.note.name + error.note.octave + ").");
}
);
/*
if (
this.checkOscCommand(message.address, this.mixerProtocol.fromMixer.CHANNEL_VU)
) {
if (this.store.settings[0].mixerProtocol === 'behringer') {
behringerMeter(message.args);
} else {
let ch = message.address.split("/")[2];
window.storeRedux.dispatch({
type:'SET_VU_LEVEL',
channel: ch - 1,
level: message.args[0]
});
}
}
if (
this.checkOscCommand(message.address, this.mixerProtocol.fromMixer.CHANNEL_NAME)
) {
let ch = message.address.split("/")[2];
window.storeRedux.dispatch({
type:'SET_CHANNEL_LABEL',
channel: ch - 1,
label: message.args[0]
});
console.log("OSC message: ", message.address);
}
*/
}

sendOutMessage(CtrlMessage: string, channel: number, value: string) {
this.midiOutput.sendControlChange(CtrlMessage, value, channel);
}

updateOutLevel(channelIndex: number) {
if (this.remoteProtocol.mode === "master" && this.store.channels[0].channel[channelIndex].pgmOn) {
window.storeRedux.dispatch({
type:'SET_OUTPUT_LEVEL',
channel: channelIndex,
level: this.store.channels[0].channel[channelIndex].faderLevel
});
}

this.sendOutMessage(
this.remoteProtocol.toRemote.STATE_CHANNEL_FADER_LEVEL,
channelIndex+1,
this.store.channels[0].channel[channelIndex].faderLevel
);
}

updatePflState(channelIndex: number) {

if (this.store.channels[0].channel[channelIndex].pflOn = true) {
this.sendOutMessage(
this.remoteProtocol.toRemote.PFL_ON.oscMessage,
channelIndex+1,
this.remoteProtocol.toRemote.PFL_ON.value
);
} else {
this.sendOutMessage(
this.remoteProtocol.toRemote.PFL_OFF.oscMessage,
channelIndex+1,
this.remoteProtocol.toRemote.PFL_OFF.value
);
}
}


updateFadeIOLevel(channelIndex: number, outputLevel: number) {
this.sendOutMessage(
this.remoteProtocol.toRemote.STATE_CHANNEL_FADER_LEVEL,
channelIndex+1,
String(outputLevel)
);
}

}

0 comments on commit 5ed8364

Please sign in to comment.