Merge mixer for BAPSicle

This commit is contained in:
Matthew Stratford 2021-06-02 19:57:15 +01:00
parent b9cc304e95
commit d038c752cb

View file

@ -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);
}; };