From d1034563b6c82d599103602ffc94748d06217cc3 Mon Sep 17 00:00:00 2001 From: bjoluc Date: Wed, 24 Apr 2024 09:30:44 +0200 Subject: [PATCH] chore: Export individual encoder page configs for easier composition in device config files --- src/device-configs/behringer_xtouch-one.ts | 31 +- src/device-configs/index.d.ts | 2 +- src/device-configs/ssl_uf1.ts | 18 +- src/mapping/encoders/index.ts | 240 +-------------- src/mapping/encoders/page-configs.ts | 327 +++++++++++++++++++++ 5 files changed, 357 insertions(+), 261 deletions(-) create mode 100644 src/mapping/encoders/page-configs.ts diff --git a/src/device-configs/behringer_xtouch-one.ts b/src/device-configs/behringer_xtouch-one.ts index 3c5383c..337f323 100644 --- a/src/device-configs/behringer_xtouch-one.ts +++ b/src/device-configs/behringer_xtouch-one.ts @@ -7,8 +7,9 @@ import { DeviceConfig } from "."; import { JogWheel } from "/decorators/surface-elements/JogWheel"; import { Lamp } from "/decorators/surface-elements/Lamp"; import { LedButton } from "/decorators/surface-elements/LedButton"; -import { EncoderDisplayMode, LedPushEncoder } from "/decorators/surface-elements/LedPushEncoder"; +import { LedPushEncoder } from "/decorators/surface-elements/LedPushEncoder"; import { TouchSensitiveMotorFader } from "/decorators/surface-elements/TouchSensitiveFader"; +import * as encoderPageConfigs from "/mapping/encoders/page-configs"; import { createElements } from "/util"; export const deviceConfig: DeviceConfig = { @@ -163,38 +164,24 @@ export const deviceConfig: DeviceConfig = { }; }, - configureEncoderAssignments(defaultEncoderMapping, page) { + configureEncoderMapping() { return [ // Pan, Monitor, Gain, LC, HC (F1) { activatorButtonSelector: (device) => device.controlSectionElements.buttons.function[0], pages: [ - ...[...defaultEncoderMapping[0].pages, ...defaultEncoderMapping[1].pages].filter((page) => - ["Pan", "Monitor", "Input Gain", "Low Cut", "High Cut"].includes(page.name), - ), + encoderPageConfigs.pan, + encoderPageConfigs.monitor, + encoderPageConfigs.inputGain, + encoderPageConfigs.lowCut, + encoderPageConfigs.highCut, ], }, // Sends 1-3 (F2) { activatorButtonSelector: (device) => device.controlSectionElements.buttons.function[1], - pages: createElements(3, (slotId) => { - return { - name: `Send Slot`, - assignments: (channel) => { - const sendSlot = channel.mSends.getByIndex(slotId); - - return { - encoderValue: sendSlot.mLevel, - encoderValueName: `Send ${slotId + 1}`, - displayMode: EncoderDisplayMode.SingleDot, - encoderValueDefault: 0.7890865802764893, - pushToggleValue: sendSlot.mOn, - }; - }, - areAssignmentsChannelRelated: true, - }; - }), + pages: createElements(3, (slotId) => encoderPageConfigs.sendSlot(slotId)), }, ]; }, diff --git a/src/device-configs/index.d.ts b/src/device-configs/index.d.ts index c09d9eb..737df1d 100644 --- a/src/device-configs/index.d.ts +++ b/src/device-configs/index.d.ts @@ -207,7 +207,7 @@ export interface DeviceConfig { * * The default config is defined in {@link file://./../mapping/encoders/index.ts} */ - configureEncoderAssignments?( + configureEncoderMapping?( defaultEncoderMappings: EncoderMappingConfig[], page: MR_FactoryMappingPage, ): EncoderMappingConfig[]; diff --git a/src/device-configs/ssl_uf1.ts b/src/device-configs/ssl_uf1.ts index 96624c0..6cff165 100644 --- a/src/device-configs/ssl_uf1.ts +++ b/src/device-configs/ssl_uf1.ts @@ -6,8 +6,9 @@ import { DeviceConfig } from "."; import { JogWheel } from "/decorators/surface-elements/JogWheel"; import { LedButton } from "/decorators/surface-elements/LedButton"; -import { EncoderDisplayMode, LedPushEncoder } from "/decorators/surface-elements/LedPushEncoder"; +import { LedPushEncoder } from "/decorators/surface-elements/LedPushEncoder"; import { TouchSensitiveMotorFader } from "/decorators/surface-elements/TouchSensitiveFader"; +import { focusedQuickControls as makeFocusedQuickControlsEncoderPageConfig } from "/mapping/encoders/page-configs"; import { createElements } from "/util"; export const deviceConfig: DeviceConfig = { @@ -217,22 +218,11 @@ export const deviceConfig: DeviceConfig = { }; }, - configureEncoderAssignments(defaultEncoderMapping, page) { - const focusedQuickControls = page.mHostAccess.mFocusedQuickControls; - + configureEncoderMapping(defaultEncoderMapping, page) { const instrumentEncoderMapping = defaultEncoderMapping.pop()!; // Replace the instrument encoder assignment with quick controls - instrumentEncoderMapping.pages[0] = { - name: "Quick Controls", - assignments: (_mixerChannel, channelIndex) => { - return { - encoderValue: focusedQuickControls.getByIndex(channelIndex), - displayMode: EncoderDisplayMode.SingleDot, - }; - }, - areAssignmentsChannelRelated: false, - }; + instrumentEncoderMapping.pages[0] = makeFocusedQuickControlsEncoderPageConfig(page.mHostAccess); // Make it the default encoder mapping by defining it first return [instrumentEncoderMapping, ...defaultEncoderMapping]; diff --git a/src/mapping/encoders/index.ts b/src/mapping/encoders/index.ts index f060c11..5e68c7f 100644 --- a/src/mapping/encoders/index.ts +++ b/src/mapping/encoders/index.ts @@ -1,12 +1,9 @@ -import { mDefaults } from "midiremote_api_v1"; import { EncoderMapper, EncoderMappingConfig } from "./EncoderMapper"; -import { EncoderAssignmentConfig } from "./EncoderPage"; -import { config, deviceConfig } from "/config"; -import { EncoderDisplayMode } from "/decorators/surface-elements/LedPushEncoder"; +import * as pageConfigs from "./page-configs"; +import { deviceConfig } from "/config"; import { Device, MainDevice } from "/devices"; import { SegmentDisplayManager } from "/midi/managers/SegmentDisplayManager"; import { GlobalState } from "/state"; -import { createElements } from "/util"; export function bindEncoders( page: MR_FactoryMappingPage, @@ -26,257 +23,52 @@ export function bindEncoders( const selectAssignButtons = (device: MainDevice) => device.controlSectionElements.buttons.encoderAssign; - const mMixerChannel = page.mHostAccess.mTrackSelection.mMixerChannel; - const mChannelEQ = mMixerChannel.mChannelEQ; - const mSends = mMixerChannel.mSends; - const sendSlotsCount = mDefaults.getNumberOfSendSlots(); - const insertEffectsViewer = mMixerChannel.mInsertAndStripEffects - .makeInsertEffectViewer("Inserts") - .followPluginWindowInFocus(); - const mStripEffects = mMixerChannel.mInsertAndStripEffects.mStripEffects; + const hostAccess = page.mHostAccess; let encoderMappingConfigs: EncoderMappingConfig[] = [ // Pan (Defining Pan first so it is activated by default) { activatorButtonSelector: (device) => selectAssignButtons(device).pan, - pages: [ - { - name: "Pan", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.BoostOrCut, - encoderValue: mixerBankChannel.mValue.mPan, - encoderValueDefault: 0.5, - pushToggleValue: mixerBankChannel.mValue.mMonitorEnable, - onPush: config.resetPanOnEncoderPush - ? (context, encoder) => { - encoder.mEncoderValue.setProcessValue(context, 0.5); - } - : undefined, - }), - areAssignmentsChannelRelated: true, - }, - ], + pages: [pageConfigs.pan], }, // Track { activatorButtonSelector: (device) => selectAssignButtons(device).track, pages: [ - { - name: "Monitor", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.Wrap, - encoderValue: mixerBankChannel.mValue.mMonitorEnable, - encoderValueDefault: 0, - pushToggleValue: mixerBankChannel.mValue.mMonitorEnable, - }), - areAssignmentsChannelRelated: true, - }, - { - name: "Input Gain", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.BoostOrCut, - encoderValue: mixerBankChannel.mPreFilter.mGain, - encoderValueDefault: 0.5, - }), - areAssignmentsChannelRelated: true, - }, - { - name: "Input Phase", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.Wrap, - encoderValue: mixerBankChannel.mPreFilter.mPhaseSwitch, - encoderValueDefault: 0, - }), - areAssignmentsChannelRelated: true, - }, - { - name: "Low Cut", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.Wrap, - encoderValue: mixerBankChannel.mPreFilter.mLowCutFreq, - encoderValueDefault: 0, - pushToggleValue: mixerBankChannel.mPreFilter.mLowCutOn, - }), - areAssignmentsChannelRelated: true, - }, - { - name: "High Cut", - assignments: (mixerBankChannel) => ({ - displayMode: EncoderDisplayMode.Wrap, - encoderValue: mixerBankChannel.mPreFilter.mHighCutFreq, - encoderValueDefault: 1, - pushToggleValue: mixerBankChannel.mPreFilter.mHighCutOn, - }), - areAssignmentsChannelRelated: true, - }, - { - name: "Track Quick Controls", - assignments: (mixerBankChannel, channelIndex) => { - return { - encoderValue: mMixerChannel.mQuickControls.getByIndex(channelIndex), - displayMode: EncoderDisplayMode.SingleDot, - }; - }, - areAssignmentsChannelRelated: false, - }, + pageConfigs.monitor, + pageConfigs.inputGain, + pageConfigs.inputPhase, + pageConfigs.lowCut, + pageConfigs.highCut, + pageConfigs.trackQuickControls(hostAccess), ], }, // EQ { activatorButtonSelector: (device) => selectAssignButtons(device).eq, - pages: [ - { - name: "EQ", - assignments: [ - mChannelEQ.mBand1, - mChannelEQ.mBand2, - mChannelEQ.mBand3, - mChannelEQ.mBand4, - ].flatMap((band, bandIndex) => [ - { - displayMode: EncoderDisplayMode.SingleDot, - encoderValue: band.mFreq, - encoderValueDefault: [ - 0.2810622751712799, 0.47443774342536926, 0.5877489447593689, 0.889056384563446, - ][bandIndex], - pushToggleValue: band.mOn, - }, - { - displayMode: EncoderDisplayMode.BoostOrCut, - encoderValue: band.mGain, - pushToggleValue: band.mOn, - onShiftPush: (context, encoder) => { - encoder.mEncoderValue.setProcessValue( - context, - 1 - encoder.mEncoderValue.getProcessValue(context), - ); - }, - }, - { - displayMode: EncoderDisplayMode.SingleDot, - encoderValue: band.mQ, - pushToggleValue: band.mOn, - encoderValueDefault: 0.0833333358168602, - }, - { - displayMode: EncoderDisplayMode.SingleDot, - encoderValue: band.mFilterType, - pushToggleValue: band.mOn, - encoderValueDefault: [0.7142857313156128, 1, 1, 0.7142857313156128][bandIndex], - }, - ]), - areAssignmentsChannelRelated: false, - }, - ], + pages: [pageConfigs.eq(hostAccess)], }, // Send { activatorButtonSelector: (device) => selectAssignButtons(device).send, - pages: [ - { - name: "Sends", - assignments: [ - ...createElements(sendSlotsCount, (slotIndex) => { - const sendSlot = mSends.getByIndex(slotIndex); - return { - encoderValue: sendSlot.mLevel, - displayMode: EncoderDisplayMode.SingleDot, - encoderValueDefault: 0.7890865802764893, - pushToggleValue: sendSlot.mOn, - }; - }), - ...createElements(sendSlotsCount, (slotIndex) => { - const sendSlot = mSends.getByIndex(slotIndex); - return { - encoderValue: sendSlot.mPrePost, - displayMode: EncoderDisplayMode.Wrap, - encoderValueDefault: 0, - pushToggleValue: sendSlot.mPrePost, - }; - }), - ], - areAssignmentsChannelRelated: false, - }, - ], + pages: [pageConfigs.sends(hostAccess)], }, // Plug-In - { - activatorButtonSelector: (device) => selectAssignButtons(device).plugin, - pages: [ - { - name: "Plugin", - assignments: () => { - const parameterValue = insertEffectsViewer.mParameterBankZone.makeParameterValue(); - return { - encoderValue: parameterValue, - displayMode: EncoderDisplayMode.SingleDot, - }; - }, - areAssignmentsChannelRelated: false, - }, - ], - enhanceMapping: ([pluginEncoderPage], activatorButtons) => { - for (const button of activatorButtons) { - for (const subPage of [ - pluginEncoderPage.subPages.default, - pluginEncoderPage.subPages.flip, - ]) { - page - .makeActionBinding( - button.mSurfaceValue, - insertEffectsViewer.mParameterBankZone.mAction.mNextBank, - ) - .setSubPage(subPage); - } - } - }, - }, + pageConfigs.pluginMappingConfig(page, (device) => selectAssignButtons(device).plugin), // Instrument { activatorButtonSelector: (device) => selectAssignButtons(device).instrument, - pages: [ - { - name: "VST Quick Controls", - assignments: () => { - return { - encoderValue: - mMixerChannel.mInstrumentPluginSlot.mParameterBankZone.makeParameterValue(), - displayMode: EncoderDisplayMode.SingleDot, - }; - }, - areAssignmentsChannelRelated: false, - }, - { - name: "Channel Strip", - assignments: [ - mStripEffects.mGate, - mStripEffects.mCompressor, - mStripEffects.mTools, - mStripEffects.mSaturator, - mStripEffects.mLimiter, - ].flatMap((stripEffect) => { - return createElements(8, () => { - const parameterValue = stripEffect.mParameterBankZone.makeParameterValue(); - return { - encoderValue: parameterValue, - displayMode: EncoderDisplayMode.SingleDot, - pushToggleValue: stripEffect.mBypass, - }; - }); - }), - areAssignmentsChannelRelated: false, - }, - ], + pages: [pageConfigs.vstQuickControls(hostAccess), pageConfigs.stripEffects(hostAccess)], }, ]; - if (deviceConfig.configureEncoderAssignments) { - encoderMappingConfigs = deviceConfig.configureEncoderAssignments(encoderMappingConfigs, page); + if (deviceConfig.configureEncoderMapping) { + encoderMappingConfigs = deviceConfig.configureEncoderMapping(encoderMappingConfigs, page); } encoderMapper.applyEncoderMappingConfigs(encoderMappingConfigs); diff --git a/src/mapping/encoders/page-configs.ts b/src/mapping/encoders/page-configs.ts new file mode 100644 index 0000000..d537ab1 --- /dev/null +++ b/src/mapping/encoders/page-configs.ts @@ -0,0 +1,327 @@ +import { mDefaults } from "midiremote_api_v1"; +import { EncoderMappingConfig } from "./EncoderMapper"; +import { EncoderAssignmentConfig, EncoderPageConfig } from "./EncoderPage"; +import { config } from "/config"; +import { LedButton } from "/decorators/surface-elements/LedButton"; +import { EncoderDisplayMode } from "/decorators/surface-elements/LedPushEncoder"; +import { MainDevice } from "/devices"; +import { createElements } from "/util"; + +const sendSlotsCount = mDefaults.getNumberOfSendSlots(); + +export const pan: EncoderPageConfig = { + name: "Pan", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.BoostOrCut, + encoderValue: mixerBankChannel.mValue.mPan, + encoderValueDefault: 0.5, + pushToggleValue: mixerBankChannel.mValue.mMonitorEnable, + onPush: config.resetPanOnEncoderPush + ? (context, encoder) => { + encoder.mEncoderValue.setProcessValue(context, 0.5); + } + : undefined, + }), + areAssignmentsChannelRelated: true, +}; + +export const monitor: EncoderPageConfig = { + name: "Monitor", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.Wrap, + encoderValue: mixerBankChannel.mValue.mMonitorEnable, + encoderValueDefault: 0, + pushToggleValue: mixerBankChannel.mValue.mMonitorEnable, + }), + areAssignmentsChannelRelated: true, +}; + +export const inputGain: EncoderPageConfig = { + name: "Input Gain", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.BoostOrCut, + encoderValue: mixerBankChannel.mPreFilter.mGain, + encoderValueDefault: 0.5, + }), + areAssignmentsChannelRelated: true, +}; + +export const inputPhase: EncoderPageConfig = { + name: "Input Phase", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.Wrap, + encoderValue: mixerBankChannel.mPreFilter.mPhaseSwitch, + encoderValueDefault: 0, + }), + areAssignmentsChannelRelated: true, +}; + +export const lowCut: EncoderPageConfig = { + name: "Low Cut", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.Wrap, + encoderValue: mixerBankChannel.mPreFilter.mLowCutFreq, + encoderValueDefault: 0, + pushToggleValue: mixerBankChannel.mPreFilter.mLowCutOn, + }), + areAssignmentsChannelRelated: true, +}; + +export const highCut: EncoderPageConfig = { + name: "High Cut", + assignments: (mixerBankChannel) => ({ + displayMode: EncoderDisplayMode.Wrap, + encoderValue: mixerBankChannel.mPreFilter.mHighCutFreq, + encoderValueDefault: 1, + pushToggleValue: mixerBankChannel.mPreFilter.mHighCutOn, + }), + areAssignmentsChannelRelated: true, +}; + +export const trackQuickControls = (hostAccess: MR_HostAccess): EncoderPageConfig => ({ + name: "Track Quick Controls", + assignments: (mixerBankChannel, channelIndex) => { + return { + encoderValue: + hostAccess.mTrackSelection.mMixerChannel.mQuickControls.getByIndex(channelIndex), + displayMode: EncoderDisplayMode.SingleDot, + }; + }, + areAssignmentsChannelRelated: false, +}); + +export const eq = (hostAccess: MR_HostAccess): EncoderPageConfig => { + const mChannelEQ = hostAccess.mTrackSelection.mMixerChannel.mChannelEQ; + + return { + name: "EQ", + assignments: [ + mChannelEQ.mBand1, + mChannelEQ.mBand2, + mChannelEQ.mBand3, + mChannelEQ.mBand4, + ].flatMap((band, bandIndex) => [ + { + displayMode: EncoderDisplayMode.SingleDot, + encoderValue: band.mFreq, + encoderValueDefault: [ + 0.2810622751712799, 0.47443774342536926, 0.5877489447593689, 0.889056384563446, + ][bandIndex], + pushToggleValue: band.mOn, + }, + { + displayMode: EncoderDisplayMode.BoostOrCut, + encoderValue: band.mGain, + pushToggleValue: band.mOn, + onShiftPush: (context, encoder) => { + encoder.mEncoderValue.setProcessValue( + context, + 1 - encoder.mEncoderValue.getProcessValue(context), + ); + }, + }, + { + displayMode: EncoderDisplayMode.SingleDot, + encoderValue: band.mQ, + pushToggleValue: band.mOn, + encoderValueDefault: 0.0833333358168602, + }, + { + displayMode: EncoderDisplayMode.SingleDot, + encoderValue: band.mFilterType, + pushToggleValue: band.mOn, + encoderValueDefault: [0.7142857313156128, 1, 1, 0.7142857313156128][bandIndex], + }, + ]), + areAssignmentsChannelRelated: false, + }; +}; + +export const sends = (hostAccess: MR_HostAccess): EncoderPageConfig => { + const mSends = hostAccess.mTrackSelection.mMixerChannel.mSends; + + return { + name: "Sends", + assignments: [ + ...createElements(sendSlotsCount, (slotIndex) => { + const sendSlot = mSends.getByIndex(slotIndex); + return { + encoderValue: sendSlot.mLevel, + displayMode: EncoderDisplayMode.SingleDot, + encoderValueDefault: 0.7890865802764893, + pushToggleValue: sendSlot.mOn, + }; + }), + ...createElements(sendSlotsCount, (slotIndex) => { + const sendSlot = mSends.getByIndex(slotIndex); + return { + encoderValue: sendSlot.mPrePost, + displayMode: EncoderDisplayMode.Wrap, + encoderValueDefault: 0, + pushToggleValue: sendSlot.mPrePost, + }; + }), + ], + areAssignmentsChannelRelated: false, + }; +}; + +export const vstQuickControls = (hostAccess: MR_HostAccess): EncoderPageConfig => ({ + name: "VST Quick Controls", + assignments: () => { + return { + encoderValue: + hostAccess.mTrackSelection.mMixerChannel.mInstrumentPluginSlot.mParameterBankZone.makeParameterValue(), + displayMode: EncoderDisplayMode.SingleDot, + }; + }, + areAssignmentsChannelRelated: false, +}); + +type StripEffectSlot = + | MR_HostStripEffectSlotGate + | MR_HostStripEffectSlotCompressor + | MR_HostStripEffectSlotTools + | MR_HostStripEffectSlotSaturator + | MR_HostStripEffectSlotLimiter; + +const makeStripEffectAssignments = (stripEffect: StripEffectSlot) => { + return createElements(8, () => { + const parameterValue = stripEffect.mParameterBankZone.makeParameterValue(); + return { + encoderValue: parameterValue, + displayMode: EncoderDisplayMode.SingleDot, + pushToggleValue: stripEffect.mBypass, + }; + }); +}; + +export const stripEffects = (hostAccess: MR_HostAccess): EncoderPageConfig => { + const mStripEffects = + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects; + + return { + name: "Channel Strip", + assignments: [ + mStripEffects.mGate, + mStripEffects.mCompressor, + mStripEffects.mTools, + mStripEffects.mSaturator, + mStripEffects.mLimiter, + ].flatMap(makeStripEffectAssignments), + areAssignmentsChannelRelated: false, + }; +}; + +const makeStripEffectEncoderPageConfig = ( + name: string, + stripEffect: StripEffectSlot, +): EncoderPageConfig => { + return { + name, + assignments: makeStripEffectAssignments(stripEffect), + areAssignmentsChannelRelated: false, + }; +}; + +export const stripEffectGate = (hostAccess: MR_HostAccess) => + makeStripEffectEncoderPageConfig( + "Gate", + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects.mGate, + ); + +export const stripEffectCompressor = (hostAccess: MR_HostAccess) => + makeStripEffectEncoderPageConfig( + "Compressor", + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects.mCompressor, + ); + +export const stripEffectTools = (hostAccess: MR_HostAccess) => + makeStripEffectEncoderPageConfig( + "Tools", + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects.mTools, + ); + +export const stripEffectSaturator = (hostAccess: MR_HostAccess) => + makeStripEffectEncoderPageConfig( + "Saturator", + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects.mSaturator, + ); + +export const stripEffectLimiter = (hostAccess: MR_HostAccess) => + makeStripEffectEncoderPageConfig( + "Limiter", + hostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects.mStripEffects.mLimiter, + ); + +/** + * Not a page config, I know. But I'd like to make it a page config in the future (the + * `enhanceMapping` logic is currently preventing this). + **/ +export const pluginMappingConfig = ( + page: MR_FactoryMappingPage, + activatorButtonSelector: (device: MainDevice) => LedButton, +): EncoderMappingConfig => { + const insertEffectsViewer = page.mHostAccess.mTrackSelection.mMixerChannel.mInsertAndStripEffects + .makeInsertEffectViewer("Inserts") + .followPluginWindowInFocus(); + + return { + activatorButtonSelector, + pages: [ + { + name: "Plugin", + assignments: () => { + const parameterValue = insertEffectsViewer.mParameterBankZone.makeParameterValue(); + return { + encoderValue: parameterValue, + displayMode: EncoderDisplayMode.SingleDot, + }; + }, + areAssignmentsChannelRelated: false, + }, + ], + enhanceMapping: ([pluginEncoderPage], activatorButtons) => { + for (const button of activatorButtons) { + for (const subPage of [ + pluginEncoderPage.subPages.default, + pluginEncoderPage.subPages.flip, + ]) { + page + .makeActionBinding( + button.mSurfaceValue, + insertEffectsViewer.mParameterBankZone.mAction.mNextBank, + ) + .setSubPage(subPage); + } + } + }, + }; +}; + +export const focusedQuickControls = (hostAccess: MR_HostAccess): EncoderPageConfig => ({ + name: "Focused Quick Controls", + assignments: (_mixerChannel, channelIndex) => { + return { + encoderValue: hostAccess.mFocusedQuickControls.getByIndex(channelIndex), + displayMode: EncoderDisplayMode.SingleDot, + }; + }, + areAssignmentsChannelRelated: false, +}); + +export const sendSlot = (slotId: number): EncoderPageConfig => ({ + name: "Send Slot", + assignments: (channel) => { + const sendSlot = channel.mSends.getByIndex(slotId); + + return { + encoderValue: sendSlot.mLevel, + encoderValueName: `Send ${slotId + 1}`, + displayMode: EncoderDisplayMode.Wrap, + encoderValueDefault: 0.7890865802764893, + pushToggleValue: sendSlot.mOn, + }; + }, + areAssignmentsChannelRelated: true, +});