Merge mixer for BAPSicle
This commit is contained in:
parent
b9cc304e95
commit
d038c752cb
1 changed files with 141 additions and 57 deletions
|
@ -3,6 +3,7 @@ import {
|
||||||
PayloadAction,
|
PayloadAction,
|
||||||
Dispatch,
|
Dispatch,
|
||||||
Middleware,
|
Middleware,
|
||||||
|
MiddlewareAPI,
|
||||||
} from "@reduxjs/toolkit";
|
} from "@reduxjs/toolkit";
|
||||||
import fetchProgress, { FetchProgressData } from "fetch-progress";
|
import fetchProgress, { FetchProgressData } from "fetch-progress";
|
||||||
import Between from "between.js";
|
import Between from "between.js";
|
||||||
|
@ -40,6 +41,8 @@ interface PlayerState {
|
||||||
volume: number;
|
volume: number;
|
||||||
gain: number;
|
gain: number;
|
||||||
trim: number;
|
trim: number;
|
||||||
|
micAutoDuck: boolean;
|
||||||
|
pfl: boolean;
|
||||||
timeCurrent: number;
|
timeCurrent: number;
|
||||||
timeRemaining: number;
|
timeRemaining: number;
|
||||||
timeLength: number;
|
timeLength: number;
|
||||||
|
@ -68,8 +71,11 @@ const BasePlayerState: PlayerState = {
|
||||||
loading: -1,
|
loading: -1,
|
||||||
state: "stopped",
|
state: "stopped",
|
||||||
volume: 1,
|
volume: 1,
|
||||||
|
volumeEnum: "full",
|
||||||
gain: 0,
|
gain: 0,
|
||||||
trim: defaultTrimDB,
|
micAutoDuck: false,
|
||||||
|
trim: DEFAULT_TRIM_DB,
|
||||||
|
pfl: false,
|
||||||
timeCurrent: 0,
|
timeCurrent: 0,
|
||||||
timeRemaining: 0,
|
timeRemaining: 0,
|
||||||
timeLength: 0,
|
timeLength: 0,
|
||||||
|
@ -171,6 +177,24 @@ const mixerState = createSlice({
|
||||||
) {
|
) {
|
||||||
state.players[action.payload.player].trim = action.payload.trim;
|
state.players[action.payload.player].trim = action.payload.trim;
|
||||||
},
|
},
|
||||||
|
setPlayerMicAutoDuck(
|
||||||
|
state,
|
||||||
|
action: PayloadAction<{
|
||||||
|
player: number;
|
||||||
|
enabled: boolean;
|
||||||
|
}>
|
||||||
|
) {
|
||||||
|
state.players[action.payload.player].micAutoDuck = action.payload.enabled;
|
||||||
|
},
|
||||||
|
setPlayerPFL(
|
||||||
|
state,
|
||||||
|
action: PayloadAction<{
|
||||||
|
player: number;
|
||||||
|
enabled: boolean;
|
||||||
|
}>
|
||||||
|
) {
|
||||||
|
state.players[action.payload.player].pfl = action.payload.enabled;
|
||||||
|
},
|
||||||
setLoadedItemIntro(
|
setLoadedItemIntro(
|
||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
|
@ -761,6 +785,7 @@ export const {
|
||||||
setRepeat,
|
setRepeat,
|
||||||
setTracklistItemID,
|
setTracklistItemID,
|
||||||
setMicBaseGain,
|
setMicBaseGain,
|
||||||
|
setPlayerMicAutoDuck,
|
||||||
} = mixerState.actions;
|
} = mixerState.actions;
|
||||||
|
|
||||||
export const toggleAutoAdvance = (player: number): AppThunk => (
|
export const toggleAutoAdvance = (player: number): AppThunk => (
|
||||||
|
@ -893,6 +918,34 @@ export const setChannelTrim = (player: number, val: number): AppThunk => async (
|
||||||
audioEngine.players[player]?.setTrim(val);
|
audioEngine.players[player]?.setTrim(val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setChannelPFL = (
|
||||||
|
player: number,
|
||||||
|
enabled: boolean
|
||||||
|
): AppThunk => async (dispatch) => {
|
||||||
|
if (
|
||||||
|
enabled &&
|
||||||
|
typeof audioEngine.players[player] !== "undefined" &&
|
||||||
|
!audioEngine.players[player]?.isPlaying &&
|
||||||
|
player !== PLAYER_ID_PREVIEW // The Preview player is setting PFL itself when it plays.
|
||||||
|
) {
|
||||||
|
dispatch(setVolume(player, "off", false)); // This does nothing for Preview player (it's not routed.)
|
||||||
|
dispatch(play(player));
|
||||||
|
}
|
||||||
|
// If the player number is -1, do all channels.
|
||||||
|
if (player === -1) {
|
||||||
|
if (!enabled) {
|
||||||
|
dispatch(stop(PLAYER_ID_PREVIEW)); // Stop the Preview player!
|
||||||
|
}
|
||||||
|
for (let i = 0; i < audioEngine.players.length; i++) {
|
||||||
|
dispatch(mixerState.actions.setPlayerPFL({ player: i, enabled: false }));
|
||||||
|
audioEngine.setPFL(i, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch(mixerState.actions.setPlayerPFL({ player, enabled }));
|
||||||
|
audioEngine.setPFL(player, enabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const openMicrophone = (
|
export const openMicrophone = (
|
||||||
micID: string,
|
micID: string,
|
||||||
micMapping: ChannelMapping
|
micMapping: ChannelMapping
|
||||||
|
@ -973,70 +1026,101 @@ export const mixerMiddleware: Middleware<{}, RootState, Dispatch<any>> = (
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (newState.mic.baseGain !== oldState.mic.baseGain) {
|
||||||
|
audioEngine.setMicCalibrationGain(newState.mic.baseGain);
|
||||||
|
}
|
||||||
|
if (newState.mic.volume !== oldState.mic.volume) {
|
||||||
|
audioEngine.setMicVolume(newState.mic.volume);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleKeyboardShortcut = (
|
||||||
|
store: MiddlewareAPI<Dispatch<any>>,
|
||||||
|
channel: number,
|
||||||
|
command: string
|
||||||
|
): AppThunk => () => {
|
||||||
|
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
|
||||||
|
sendBAPSicleChannel({ channel: channel, command: command });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (command) {
|
||||||
|
case "PLAY":
|
||||||
|
store.dispatch(play(channel));
|
||||||
|
break;
|
||||||
|
case "PAUSE":
|
||||||
|
store.dispatch(pause(channel));
|
||||||
|
break;
|
||||||
|
case "STOP":
|
||||||
|
store.dispatch(stop(channel));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const mixerKeyboardShortcutsMiddleware: Middleware<
|
export const mixerKeyboardShortcutsMiddleware: Middleware<
|
||||||
{},
|
{},
|
||||||
RootState,
|
RootState,
|
||||||
Dispatch<any>
|
Dispatch<any>
|
||||||
> = (store) => {
|
> = (store) => {
|
||||||
// The F keys will only work in places like Electron (NeutronStudio) where they don't trigger browser functions.
|
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
|
||||||
Keys("f1", () => {
|
// The F keys will only work in places like Electron (NeutronStudio) where they don't trigger browser functions.
|
||||||
sendBAPSicleChannel({ channel: 0, command: "PLAY" });
|
Keys("f1", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "PLAY");
|
||||||
Keys("f2", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 0, command: "PAUSE" });
|
Keys("f2", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "PAUSE");
|
||||||
Keys("f3", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 0, command: "STOP" });
|
Keys("f3", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "STOP");
|
||||||
Keys("f5", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "PLAY" });
|
Keys("f5", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "PLAY");
|
||||||
Keys("f6", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "PAUSE" });
|
Keys("f6", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "PAUSE");
|
||||||
Keys("f7", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "STOP" });
|
Keys("f7", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "STOP");
|
||||||
Keys("f9", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "PLAY" });
|
Keys("f9", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "PLAY");
|
||||||
Keys("f10", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "PAUSE" });
|
Keys("f10", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "PAUSE");
|
||||||
Keys("f11", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "STOP" });
|
Keys("f11", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "STOP");
|
||||||
|
});
|
||||||
Keys("q", () => {
|
} else {
|
||||||
sendBAPSicleChannel({ channel: 0, command: "PLAY" });
|
Keys("q", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "PLAY");
|
||||||
Keys("w", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 0, command: "PAUSE" });
|
Keys("w", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "PAUSE");
|
||||||
Keys("e", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 0, command: "STOP" });
|
Keys("e", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 0, "STOP");
|
||||||
Keys("r", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "PLAY" });
|
Keys("r", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "PLAY");
|
||||||
Keys("t", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "PAUSE" });
|
Keys("t", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "PAUSE");
|
||||||
Keys("y", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 1, command: "STOP" });
|
Keys("y", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 1, "STOP");
|
||||||
Keys("u", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "PLAY" });
|
Keys("u", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "PLAY");
|
||||||
Keys("i", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "PAUSE" });
|
Keys("i", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "PAUSE");
|
||||||
Keys("o", () => {
|
});
|
||||||
sendBAPSicleChannel({ channel: 2, command: "STOP" });
|
Keys("o", () => {
|
||||||
});
|
handleKeyboardShortcut(store, 2, "STOP");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (next) => (action) => next(action);
|
return (next) => (action) => next(action);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue