From ec5f54a93d6dadf5c2de6b672507d32cb9b95815 Mon Sep 17 00:00:00 2001 From: ericahrens Date: Sun, 5 Jul 2026 23:08:26 +0200 Subject: [PATCH 1/4] NKS Connect integrated --- .../komplete/KontrolSMk3Extension.java | 16 ++--- .../KontrolSMk3ExtensionDefinition.java | 2 +- .../NksConnectExtensionDefinition.java | 59 +++++++++++++++++++ .../komplete/midi/MidiProcessor.java | 2 +- .../com.bitwig.extension.ExtensionDefinition | 1 + 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/NksConnectExtensionDefinition.java diff --git a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/KontrolSMk3Extension.java b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/KontrolSMk3Extension.java index 3db6528a..9e67ce91 100644 --- a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/KontrolSMk3Extension.java +++ b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/KontrolSMk3Extension.java @@ -25,10 +25,12 @@ public class KontrolSMk3Extension extends KompleteKontrolExtension { protected ScrollbarModel horizontalScrollbarModel; protected double scrubDistance; protected Arranger arranger; + private final boolean isNksConnect; - public KontrolSMk3Extension(final AbstractKompleteKontrolExtensionDefinition definition, - final ControllerHost host) { + public KontrolSMk3Extension(final AbstractKompleteKontrolExtensionDefinition definition, final ControllerHost host, + final boolean isNksConnect) { super(definition, host); + this.isNksConnect = isNksConnect; } @Override @@ -52,13 +54,13 @@ public void init() { navigationLayer = new Layer(layers, "NavigationLayer"); clipSceneCursor = viewControl.getClipSceneCursor(); - final MidiIn midiIn2 = host.getMidiInPort(1); - final NoteInput noteInput = - midiIn2.createNoteInput( + if (!isNksConnect) { + final MidiIn midiIn2 = host.getMidiInPort(1); + final NoteInput noteInput = midiIn2.createNoteInput( "MIDI", "80????", "90????", "A0????", "D0????", "E0????", "B001??", "B00B??", "B040??", "B042??", "B1????"); - noteInput.setShouldConsumeEvents(true); - + noteInput.setShouldConsumeEvents(true); + } initTrackBank(); setUpTransport(); diff --git a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/KontrolSMk3ExtensionDefinition.java b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/KontrolSMk3ExtensionDefinition.java index a3543e08..7540c092 100644 --- a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/KontrolSMk3ExtensionDefinition.java +++ b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/KontrolSMk3ExtensionDefinition.java @@ -75,6 +75,6 @@ public String getHelpFilePath() { @Override public KontrolSMk3Extension createInstance(final ControllerHost host) { - return new KontrolSMk3Extension(this, host); + return new KontrolSMk3Extension(this, host, false); } } diff --git a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/NksConnectExtensionDefinition.java b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/NksConnectExtensionDefinition.java new file mode 100644 index 00000000..d95852a2 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/definition/NksConnectExtensionDefinition.java @@ -0,0 +1,59 @@ +package com.bitwig.extensions.controllers.nativeinstruments.komplete.definition; + +import java.util.UUID; + +import com.bitwig.extension.api.PlatformType; +import com.bitwig.extension.controller.AutoDetectionMidiPortNamesList; +import com.bitwig.extension.controller.api.ControllerHost; +import com.bitwig.extensions.controllers.nativeinstruments.komplete.KontrolSMk3Extension; + +public class NksConnectExtensionDefinition extends AbstractKompleteKontrolExtensionDefinition { + + private static final UUID DRIVER_ID = UUID.fromString("8b07a8e9-886c-f35b-e133-da9210306ce4"); + private static final String MODEL = "NKS Connect"; + + public NksConnectExtensionDefinition() { + super(MODEL); + } + + @Override + public String getName() { + return MODEL; + } + + @Override + public String getHardwareModel() { + return MODEL; + } + + @Override + public UUID getId() { + return DRIVER_ID; + } + + @Override + public int getNumMidiInPorts() { + return 1; + } + + @Override + public int getNumMidiOutPorts() { + return 1; + } + + @Override + public void listAutoDetectionMidiPortNames(final AutoDetectionMidiPortNamesList list, + final PlatformType platformType) { + list.add(new String[] {"NKS Connect"}, new String[] {"NKS Connect"}); + } + + @Override + public String getHelpFilePath() { + return "Controllers/Native Instruments/Kontrol S-Series/Kontrol S-Series Mk3.pdf"; + } + + @Override + public KontrolSMk3Extension createInstance(final ControllerHost host) { + return new KontrolSMk3Extension(this, host, true); + } +} diff --git a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/midi/MidiProcessor.java b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/midi/MidiProcessor.java index a892cfd6..1fd43fb3 100644 --- a/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/midi/MidiProcessor.java +++ b/src/main/java/com/bitwig/extensions/controllers/nativeinstruments/komplete/midi/MidiProcessor.java @@ -88,7 +88,7 @@ public void intoDawMode(final int protocol) { private void initProcess() { final long diff = System.currentTimeMillis() - initStartTime; - KompleteKontrolExtension.println(" Running Init Process %d kk=%s", diff, lastReportedKKInstance); + //KompleteKontrolExtension.println(" Running Init Process %d kk=%s", diff, lastReportedKKInstance); if (diff < 20000) { host.scheduleTask(this::initProcess, 1000); } diff --git a/src/main/resources/META-INF/services/com.bitwig.extension.ExtensionDefinition b/src/main/resources/META-INF/services/com.bitwig.extension.ExtensionDefinition index e8f1ee2b..0eb7ee9a 100644 --- a/src/main/resources/META-INF/services/com.bitwig.extension.ExtensionDefinition +++ b/src/main/resources/META-INF/services/com.bitwig.extension.ExtensionDefinition @@ -74,6 +74,7 @@ com.bitwig.extensions.controllers.nativeinstruments.komplete.definition.Komplete com.bitwig.extensions.controllers.nativeinstruments.komplete.definition.KompleteKontrolASeriesExtensionDefinition com.bitwig.extensions.controllers.nativeinstruments.komplete.definition.KompleteKontrolMSeriesExtensionDefinition com.bitwig.extensions.controllers.nativeinstruments.komplete.definition.KontrolSMk3ExtensionDefinition +com.bitwig.extensions.controllers.nativeinstruments.komplete.definition.NksConnectExtensionDefinition com.bitwig.extensions.controllers.neuzeitinstruments.DropExtensionDefinition From 3379f3d4404930c34040d3e8c6b28fdfb766a7d3 Mon Sep 17 00:00:00 2001 From: ericahrens Date: Thu, 6 Aug 2026 18:07:43 +0200 Subject: [PATCH 2/4] Minilab 37 Fix Shift+Lock + Encoder --- .../arturia/minilab3/MiniLab3Extension.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/bitwig/extensions/controllers/arturia/minilab3/MiniLab3Extension.java b/src/main/java/com/bitwig/extensions/controllers/arturia/minilab3/MiniLab3Extension.java index c7e5dde0..fa41eb0a 100644 --- a/src/main/java/com/bitwig/extensions/controllers/arturia/minilab3/MiniLab3Extension.java +++ b/src/main/java/com/bitwig/extensions/controllers/arturia/minilab3/MiniLab3Extension.java @@ -184,11 +184,11 @@ public void init() { private void handleSysExData(final String sysEx) { switch (sysEx) { case "f000206b7f420200406300f7": - MiniLab3Extension.println(" ==> BANK A"); + //MiniLab3Extension.println(" ==> BANK A"); toBankMode(PadBank.BANK_A); break; case "f000206b7f420200406301f7": - MiniLab3Extension.println(" ==> BANK B"); + //MiniLab3Extension.println(" ==> BANK B"); toBankMode(PadBank.BANK_B); break; case "f000206b7f420200406201f7": // Arturia Mode @@ -652,8 +652,10 @@ private void mainEncoderAction(final int dir) { encoderStateMaschine.notifyTurn(false); oled.disableValues(); switch (encoderStateMaschine.getState()) { - case INITIAL -> navigateScenesOrPads(dir); - case HOLD -> navigateParametersBanks(dir); + // Since the Encoder sends different CCs when SHIFT is held (see mainEncoderShiftAction) + // There is no conflict here. + case SHIFT, INITIAL -> navigateScenesOrPads(dir); // SHIFT State active when in Transport Lock + case SHIFT_HOLD, HOLD -> navigateParametersBanks(dir); // SHIFT State active when in Transport Lock } } From 1d1ed33c63c0633a00ce6e4e56cc94e7920d5f68 Mon Sep 17 00:00:00 2001 From: ericahrens Date: Wed, 12 Aug 2026 20:43:12 +0200 Subject: [PATCH 3/4] Erae2 Added to the mix --- .../controllers/embodme/ClipLayer.java | 485 ++++++++++++++++++ .../embodme/Erae2ControllerExtension.java | 107 ++++ .../embodme/Erae2ExtensionDefinition.java | 76 +++ .../controllers/embodme/EraeColor.java | 177 +++++++ .../embodme/EraeMidiProcessor.java | 116 +++++ .../controllers/embodme/SceneState.java | 69 +++ .../controllers/embodme/TrackState.java | 57 ++ .../Controllers/Embodme/Embodme Erae 2.pdf | Bin 0 -> 96281 bytes .../com.bitwig.extension.ExtensionDefinition | 2 + 9 files changed, 1089 insertions(+) create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/ClipLayer.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ControllerExtension.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ExtensionDefinition.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/EraeColor.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/EraeMidiProcessor.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/SceneState.java create mode 100644 src/main/java/com/bitwig/extensions/controllers/embodme/TrackState.java create mode 100644 src/main/resources/Documentation/Controllers/Embodme/Embodme Erae 2.pdf diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/ClipLayer.java b/src/main/java/com/bitwig/extensions/controllers/embodme/ClipLayer.java new file mode 100644 index 00000000..bfdf9e30 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/ClipLayer.java @@ -0,0 +1,485 @@ +package com.bitwig.extensions.controllers.embodme; + +import java.util.Arrays; +import java.util.Optional; + +import com.bitwig.extension.controller.api.ClipLauncherSlot; +import com.bitwig.extension.controller.api.ClipLauncherSlotBank; +import com.bitwig.extension.controller.api.ControllerHost; +import com.bitwig.extension.controller.api.Scene; +import com.bitwig.extension.controller.api.SceneBank; +import com.bitwig.extension.controller.api.SendBank; +import com.bitwig.extension.controller.api.SettableRangedValue; +import com.bitwig.extension.controller.api.Track; +import com.bitwig.extension.controller.api.TrackBank; +import com.bitwig.extensions.framework.view.OverviewGrid; + +public class ClipLayer { + public static final int INDEX_OFFSET_ARM = 0x21; + public static final int INDEX_OFFSET_MUTE = 0x15; + public static final int INDEX_OFFSET_SOLO = 0x9; + + public enum Mode { + VOLUME, + SENDS, + GRID + } + + private final Track rootTrack; + private int sceneOffset; + private final OverviewGrid overviewGrid; + private boolean active; + private final boolean horizontalMode; + private final EraeMidiProcessor midiProcessor; + private final TrackBank trackBank; + private final TrackState[] trackStates; + private final SceneState[] sceneStates; + private final SlotState[][] slotStates; + private final int trackSize; + private final int sceneSize; + private final int[] sliderValues = new int[128]; + private Mode currentHeightMode = Mode.GRID; + private int gridHeight; + + private class SlotState { + private final ClipLauncherSlot slot; + private final TrackState trackState; + private boolean stopQueued; + private boolean recordingQueued; + private boolean playbackQueued; + private boolean recording; + private boolean playing; + private int color; + private int displayColor; + private int state; + private boolean hasContent; + private final int sceneIndex; + + public SlotState(final ClipLauncherSlot slot, final TrackState trackState, final int sceneIndex) { + this.slot = slot; + this.trackState = trackState; + this.sceneIndex = sceneIndex; + } + + public int getTrackIndex() { + return trackState.getIndex(); + } + + public int getSceneIndex() { + return sceneIndex; + } + + public ClipLauncherSlot getSlot() { + return slot; + } + + public void setHasContent(final boolean hasContent) { + this.hasContent = hasContent; + } + + public void setStopQueued(final boolean stopQueued) { + this.stopQueued = stopQueued; + } + + public void setRecordingQueued(final boolean recordingQueued) { + this.recordingQueued = recordingQueued; + } + + public void setPlaybackQueued(final boolean playbackQueued) { + this.playbackQueued = playbackQueued; + } + + public void setRecording(final boolean recording) { + this.recording = recording; + } + + public void setPlaying(final boolean playing) { + this.playing = playing; + } + + public void setColor(final int color) { + this.color = color; + } + + public int getState() { + return state; + } + + private boolean calcState() { + final int oldState = this.state; + final int oldColor = this.displayColor; + if (!hasContent) { + if (trackState.isArmed()) { + this.displayColor = recordingQueued ? EraeColor.RED : EraeColor.RED_DIM; + } else { + this.displayColor = EraeColor.OFF; + } + if (recordingQueued || stopQueued || playbackQueued) { + this.state = EraeColor.STATE_BLINK; + } else { + this.state = EraeColor.STATE_NORMAL; + } + } else if (stopQueued) { + this.state = EraeColor.STATE_BLINK; + this.displayColor = EraeColor.GREEN; + } else if (recordingQueued) { + this.state = EraeColor.STATE_BLINK; + this.displayColor = EraeColor.RED; + } else if (playbackQueued) { + this.state = EraeColor.STATE_BLINK; + this.displayColor = color; + } else if (recording) { + this.state = EraeColor.STATE_PULSE; + this.displayColor = EraeColor.RED; + } else if (playing) { + this.state = EraeColor.STATE_PULSE; + this.displayColor = EraeColor.GREEN; + } else { + this.state = EraeColor.STATE_NORMAL; + this.displayColor = color; + } + return oldState != state || oldColor != displayColor; + } + + public int getDisplayColor() { + return displayColor; + } + } + + public ClipLayer(final ControllerHost host, final int width, final int height, + final EraeMidiProcessor midiProcessor, final boolean horizontalMode, final OverviewGrid overviewGrid) { + this.horizontalMode = horizontalMode; + this.overviewGrid = overviewGrid; + this.trackSize = horizontalMode ? height : width; + this.sceneSize = horizontalMode ? width : height; + overviewGrid.addQueuedSceneListener(this::handleQueued); + rootTrack = host.getProject().getRootTrackGroup(); + trackBank = host.createTrackBank(trackSize, 2, sceneSize); + slotStates = new SlotState[trackSize][sceneSize]; + trackStates = new TrackState[trackSize]; + sceneStates = new SceneState[sceneSize]; + Arrays.fill(sliderValues, 0); + this.gridHeight = height; + this.midiProcessor = midiProcessor; + + + for (int i = 0; i < this.trackSize; i++) { + final int trackIndex = i; + final Track track = trackBank.getItemAt(i); + trackStates[trackIndex] = new TrackState(track, i); + prepareTrackState(trackStates[trackIndex]); + for (int j = 0; j < this.sceneSize; j++) { + final int sceneIndex = j; + final ClipLauncherSlotBank slotBank = track.clipLauncherSlotBank(); + final ClipLauncherSlot slot = slotBank.getItemAt(j); + slotStates[trackIndex][sceneIndex] = new SlotState(slot, trackStates[trackIndex], sceneIndex); + prepareSlot(slotStates[trackIndex][sceneIndex]); + } + final SettableRangedValue volume = track.volume().value(); + volume.addValueObserver(128, v -> handleVolumeChange(trackIndex, v)); + final SendBank sendBank = track.sendBank(); + sendBank.getItemAt(0).value().addValueObserver(128, v -> handleSendChange(trackIndex, 0, v)); + sendBank.getItemAt(1).value().addValueObserver(128, v -> handleSendChange(trackIndex, 1, v)); + } + final SceneBank sceneBank = trackBank.sceneBank(); + sceneBank.scrollPosition().addValueObserver(sceneOffset -> { + this.sceneOffset = sceneOffset; + }); + + + for (int j = 0; j < height; j++) { + final Scene scene = sceneBank.getScene(j); + final SceneState sceneState = new SceneState(j); + sceneStates[j] = sceneState; + scene.clipCount().addValueObserver(count -> handleSceneCount(sceneState, count)); + scene.exists().addValueObserver(exists -> handleSceneExists(sceneState, exists)); + scene.color().addValueObserver((r, g, b) -> { + final int colorIndex = EraeColor.rgbToIndex(r, g, b); + sceneState.setColor(colorIndex); + updateSceneLed(sceneState); + }); + } + } + + private void handleQueued(final int index, final boolean queued) { + final int overviewOffset = overviewGrid.getSceneOffset(); + final int diff = sceneOffset - overviewOffset; + final int target = index - diff; + if (target >= 0 && target < this.sceneSize) { // TODO Questionable + sceneStates[target].setQueued(queued); + updateSceneLed(sceneStates[target]); + } + } + + private void handleSceneExists(final SceneState sceneState, final boolean exists) { + sceneState.setExists(exists); + updateSceneLed(sceneState); + } + + private void handleSceneCount(final SceneState state, final int count) { + state.setCount(count); + updateSceneLed(state); + } + + private void updateSceneLed(final SceneState state) { + final boolean changed = state.calcState(); + if (isActive() && changed && state.getIndex() < gridHeight) { + midiProcessor.sendActionButtonUpdate(state.getIndex(), state.getState(), state.getDisplayColor()); + } + } + + private void prepareTrackState(final TrackState trackState) { + trackState.getTrack().arm().addValueObserver(armed -> { + trackState.setArmed(armed); + handleArmUpdate(trackState); + }); + trackState.getTrack().mute().addValueObserver(muted -> { + trackState.setMuted(muted); + updateMuteState(trackState); + }); + trackState.getTrack().solo().addValueObserver(soloed -> { + trackState.setSolo(soloed); + updateSoloState(trackState); + }); + } + + private void handleArmUpdate(final TrackState trackState) { + if (isActive()) { + for (int sceneIndex = 0; sceneIndex < this.sceneSize; sceneIndex++) { // TODO Watch this. + final SlotState slot = slotStates[trackState.getIndex()][sceneIndex]; + if (slot.calcState()) { + sendGridUpdate(slot); + } + } + } + updateArmState(trackState); + } + + private void sendGridUpdate(final SlotState slot) { + if (horizontalMode) { + midiProcessor.sendGridButtonUpdate( + slot.getTrackIndex(), slot.getSceneIndex(), slot.getState(), slot.getDisplayColor()); + } else { + midiProcessor.sendGridButtonUpdate( + slot.getSceneIndex(), slot.getTrackIndex(), slot.getState(), slot.getDisplayColor()); + } + } + + private void updateArmState(final TrackState trackState) { + if (isActive()) { + midiProcessor.sendActionButtonUpdate( + trackState.getIndex() + INDEX_OFFSET_ARM, 0, + trackState.isArmed() ? 1 : 0); + } + } + + private void updateMuteState(final TrackState trackState) { + if (isActive()) { + midiProcessor.sendActionButtonUpdate( + trackState.getIndex() + INDEX_OFFSET_MUTE, 0, + trackState.isMuted() ? 1 : 0); + } + } + + private void updateSoloState(final TrackState trackState) { + if (isActive()) { + midiProcessor.sendActionButtonUpdate( + trackState.getIndex() + INDEX_OFFSET_SOLO, 0, + trackState.isSolo() ? 1 : 0); + } + } + + private void handleSendChange(final int trackIndex, final int sendIndex, final int value) { + final int sliderIndex = (sendIndex + 1) * 12 + trackIndex; + this.sliderValues[sliderIndex] = value; + if (active && currentHeightMode == Mode.SENDS) { + midiProcessor.sendSliderUpdate(sliderIndex, value); + } + } + + private void handleVolumeChange(final int trackIndex, final int value) { + this.sliderValues[trackIndex] = value; + if (active && currentHeightMode == Mode.VOLUME || currentHeightMode == Mode.SENDS) { + midiProcessor.sendSliderUpdate(trackIndex, value); + } + } + + private Optional getTrack(final int index, final int offset) { + final int trackIndex = index - offset; + if (trackIndex >= 0 && trackIndex < this.trackSize) { + return Optional.of(trackBank.getItemAt(trackIndex)); + } + return Optional.empty(); + } + + public void handleGridButton(final int index, final boolean pressed) { + if (index < INDEX_OFFSET_SOLO) { + trackBank.sceneBank().getScene(index).launch(); + } else if (index < INDEX_OFFSET_MUTE) { + getTrack(index, INDEX_OFFSET_SOLO).ifPresent(track -> track.solo().toggle()); + } else if (index < INDEX_OFFSET_ARM) { + getTrack(index, INDEX_OFFSET_MUTE).ifPresent(track -> track.mute().toggle()); + } else if (index < 0x2D) { + getTrack(index, INDEX_OFFSET_ARM).ifPresent(track -> track.arm().toggle()); + } else if (index == 0x3F) { + rootTrack.stop(); + } else if (index == 0x5A) { + Erae2ControllerExtension.println(" STOP Transport"); + } else if (index == 0x5B) { + Erae2ControllerExtension.println(" PLAY Transport"); + } else if (index == 0x64) { + if (horizontalMode) { + trackBank.scrollBy(-1); + } else { + trackBank.sceneBank().scrollBy(-1); + } + } else if (index == 0x65) { + if (horizontalMode) { + trackBank.scrollBy(1); + } else { + trackBank.sceneBank().scrollBy(1); + } + } else if (index == 0x66) { + if (horizontalMode) { + trackBank.sceneBank().scrollBy(-1); + } else { + trackBank.scrollBy(-1); + } + } else if (index == 0x67) { + if (horizontalMode) { + trackBank.sceneBank().scrollBy(1); + } else { + trackBank.scrollBy(1); + } + } + } + + public void handleGridButton(final int rowIndex, final int columnIndex, final boolean on) { + if (horizontalMode) { + if (rowIndex < trackSize && columnIndex < sceneSize) { + final ClipLauncherSlot clip = + trackBank.getItemAt(rowIndex).clipLauncherSlotBank().getItemAt(columnIndex); + clip.launch(); + } + } else { + if (rowIndex < sceneSize && columnIndex < trackSize) { + final ClipLauncherSlot clip = + trackBank.getItemAt(columnIndex).clipLauncherSlotBank().getItemAt(rowIndex); + clip.launch(); + } + } + } + + public void setCurrentHeightMode(final int height) { + if (this.trackSize == 12) { + switch (height) { + case 1 -> this.currentHeightMode = Mode.SENDS; + case 5 -> this.currentHeightMode = Mode.VOLUME; + case INDEX_OFFSET_SOLO -> this.currentHeightMode = Mode.GRID; + } + } else { + switch (height) { + case 1 -> this.currentHeightMode = Mode.SENDS; + case 3 -> this.currentHeightMode = Mode.VOLUME; + case 12 -> this.currentHeightMode = Mode.GRID; + } + } + this.gridHeight = height; + // Erae2ControllerExtension.println(" MODE=%s %d", this.currentHeightMode, height); + } + + public boolean isActive() { + return active; + } + + public void setActive(final boolean active) { + this.active = active; + trackBank.setShouldShowClipLauncherFeedback(active); + this.overviewGrid.setScenePosition(sceneOffset); + } + + private void triggerPadSlotUpdate(final SlotState slot) { + final boolean changed = slot.calcState(); + if (horizontalMode) { + if (isActive() && changed && slot.getTrackIndex() < gridHeight) { + sendGridUpdate(slot); + } + } else { + if (isActive() && changed && slot.getSceneIndex() < gridHeight) { + sendGridUpdate(slot); + } + } + } + + private void prepareSlot(final SlotState slot) { + slot.getSlot().hasContent().addValueObserver(content -> { + slot.setHasContent(content); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().isPlaying().addValueObserver(playing -> { + slot.setPlaying(playing); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().isStopQueued().addValueObserver(stopQueued -> { + slot.setStopQueued(stopQueued); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().isRecordingQueued().addValueObserver(recordingQueued -> { + slot.setRecordingQueued(recordingQueued); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().isRecording().addValueObserver(recording -> { + slot.setRecording(recording); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().isPlaybackQueued().addValueObserver(playback -> { + slot.setPlaybackQueued(playback); + triggerPadSlotUpdate(slot); + }); + slot.getSlot().color().addValueObserver((r, g, b) -> { + final int colorIndex = EraeColor.rgbToIndex(r, g, b); + slot.setColor(colorIndex); + triggerPadSlotUpdate(slot); + }); + } + + + public void updateState() { + for (int trackIndex = 0; trackIndex < trackSize; trackIndex++) { + for (int sceneIndex = 0; sceneIndex < gridHeight; sceneIndex++) { + final SlotState slot = slotStates[trackIndex][sceneIndex]; + sendGridUpdate(slotStates[trackIndex][sceneIndex]); + } + if (currentHeightMode == Mode.VOLUME || currentHeightMode == Mode.SENDS) { + midiProcessor.sendSliderUpdate(trackIndex, sliderValues[trackIndex]); + } + if (currentHeightMode == Mode.SENDS) { + midiProcessor.sendSliderUpdate(trackIndex + 0xC, sliderValues[trackIndex + 0xC]); + midiProcessor.sendSliderUpdate(trackIndex + 0x18, sliderValues[trackIndex + 0x18]); + } + updateSoloState(trackStates[trackIndex]); + updateMuteState(trackStates[trackIndex]); + updateArmState(trackStates[trackIndex]); + } + for (int sceneIndex = 0; sceneIndex < gridHeight; sceneIndex++) { + final SceneState state = sceneStates[sceneIndex]; + midiProcessor.sendActionButtonUpdate(sceneIndex, state.getState(), state.getDisplayColor()); + } + } + + public void handleSliderValue(final int sliderIndex, final int value) { + if (sliderValues[sliderIndex] != value) { + sliderValues[sliderIndex] = value; + final int groupIndex = sliderIndex / 12; + final int paramIndex = sliderIndex % 12; + final double val = (double) value / 127.0; + if (groupIndex == 0) { + trackBank.getItemAt(sliderIndex).volume().set(val); + } else if (groupIndex == 1) { + trackBank.getItemAt(paramIndex).sendBank().getItemAt(0).value().set(val); + } else if (groupIndex == 2) { + trackBank.getItemAt(paramIndex).sendBank().getItemAt(1).value().set(val); + } + } + } +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ControllerExtension.java b/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ControllerExtension.java new file mode 100644 index 00000000..f1463250 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ControllerExtension.java @@ -0,0 +1,107 @@ +package com.bitwig.extensions.controllers.embodme; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import com.bitwig.extension.controller.ControllerExtension; +import com.bitwig.extension.controller.ControllerExtensionDefinition; +import com.bitwig.extension.controller.api.Application; +import com.bitwig.extension.controller.api.ControllerHost; +import com.bitwig.extension.controller.api.HardwareSurface; +import com.bitwig.extension.controller.api.TrackBank; +import com.bitwig.extensions.framework.values.LayoutType; +import com.bitwig.extensions.framework.view.OverviewGrid; + +public class Erae2ControllerExtension extends ControllerExtension { + + private static ControllerHost debugHost; + private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("hh:mm:ss SSS"); + private HardwareSurface surface; + private ControllerHost host; + private EraeMidiProcessor midiProcessor; + private ClipLayer activeLayer; + private ClipLayer smallClipLayer; + private ClipLayer largeClipLayer; + private Application application; + private LayoutType panelLayout; + private OverviewGrid overviewGrid; + + public static void println(final String format, final Object... args) { + if (debugHost != null) { + final LocalDateTime now = LocalDateTime.now(); + debugHost.println(now.format(DF) + " > " + String.format(format, args)); + } + } + + protected Erae2ControllerExtension(final ControllerExtensionDefinition definition, final ControllerHost host) { + super(definition, host); + } + + @Override + public void init() { + debugHost = getHost(); + this.host = getHost(); + this.surface = host.createHardwareSurface(); + this.application = host.createApplication(); + final TrackBank maxTrackBank = host.createTrackBank(64, 1, 64, false); + overviewGrid = new OverviewGrid(maxTrackBank); + overviewGrid.initMaxBank(); + + midiProcessor = new EraeMidiProcessor(host, this); + application.panelLayout().addValueObserver(this::handleLayoutChanged); + initLayers(); + midiProcessor.init(); + } + + private void handleLayoutChanged(final String layout) { + this.panelLayout = LayoutType.toType(layout); + Erae2ControllerExtension.println(" LAYOUT = " + this.panelLayout); + } + + private void initLayers() { + smallClipLayer = new ClipLayer(host, 9, 5, midiProcessor, false, overviewGrid); + largeClipLayer = new ClipLayer(host, 12, 9, midiProcessor, false, overviewGrid); + activeLayer = smallClipLayer; + activeLayer.setActive(true); + } + + public void handleMode(final int width, final int height) { + Erae2ControllerExtension.println(" Window width=%d height=%d %s", width, height, panelLayout); + activeLayer.setActive(false); + if (width == 9) { + activeLayer = smallClipLayer; + } else if (width == 12) { + activeLayer = largeClipLayer; + } + activeLayer.setCurrentHeightMode(height); + activeLayer.setActive(true); + activeLayer.updateState(); + } + + public void handleGridButton(final int row, final int col, final boolean pressed) { + if (pressed) { + activeLayer.handleGridButton(row, col, true); + } + } + + public void handleSlider(final int sliderIndex, final int value) { + activeLayer.handleSliderValue(sliderIndex, value); + } + + public void handleIndexButton(final int index, final boolean pressed) { + if (pressed) { + activeLayer.handleGridButton(index, pressed); + } + } + + @Override + public void exit() { + + } + + @Override + public void flush() { + surface.updateHardware(); + } + +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ExtensionDefinition.java b/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ExtensionDefinition.java new file mode 100644 index 00000000..d0aac386 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/Erae2ExtensionDefinition.java @@ -0,0 +1,76 @@ +package com.bitwig.extensions.controllers.embodme; + +import java.util.UUID; + +import com.bitwig.extension.api.PlatformType; +import com.bitwig.extension.controller.AutoDetectionMidiPortNamesList; +import com.bitwig.extension.controller.ControllerExtensionDefinition; +import com.bitwig.extension.controller.api.ControllerHost; + +public class Erae2ExtensionDefinition extends ControllerExtensionDefinition { + private static final UUID DRIVER_ID = UUID.fromString("a4f71be3-f377-411d-94b2-5a913c2080a3"); + + public Erae2ExtensionDefinition() { + } + + @Override + public String getName() { + return "Erae 2"; + } + + @Override + public String getAuthor() { + return "Bitwig"; + } + + @Override + public String getVersion() { + return "0.5"; + } + + @Override + public UUID getId() { + return DRIVER_ID; + } + + @Override + public String getHardwareVendor() { + return "Embodme"; + } + + @Override + public String getHardwareModel() { + return "Erae 2"; + } + + @Override + public int getRequiredAPIVersion() { + return 24; + } + + @Override + public int getNumMidiInPorts() { + return 2; + } + + @Override + public int getNumMidiOutPorts() { + return 1; + } + + @Override + public String getHelpFilePath() { + return "Controllers/Embodme/Embodme Erae 2.pdf"; + } + + @Override + public void listAutoDetectionMidiPortNames(final AutoDetectionMidiPortNamesList list, + final PlatformType platformType) { + list.add(new String[] {"Erae 2", "MIDIIN2 (Erae 2)"}, new String[] {"Erae 2"}); + } + + @Override + public Erae2ControllerExtension createInstance(final ControllerHost host) { + return new Erae2ControllerExtension(this, host); + } +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/EraeColor.java b/src/main/java/com/bitwig/extensions/controllers/embodme/EraeColor.java new file mode 100644 index 00000000..fad5d14e --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/EraeColor.java @@ -0,0 +1,177 @@ +package com.bitwig.extensions.controllers.embodme; + +import java.util.List; + +import com.bitwig.extension.api.Color; + +public class EraeColor { + private static final List COLOR_SEQ = List.of( + new ColorMatch(0x00, 0x00, 0x00, 0x00), new ColorMatch(0x01, 0x1E, 0x1E, 0x1E), + new ColorMatch(0x02, 0x7F, 0x7F, 0x7F), new ColorMatch(0x03, 0xFF, 0xFF, 0xFF), + new ColorMatch(0x04, 0xFF, 0x4C, 0x4C), new ColorMatch(0x05, 0xFF, 0x00, 0x00), + new ColorMatch(0x06, 0x59, 0x00, 0x00), new ColorMatch(0x07, 0x19, 0x00, 0x00), + new ColorMatch(0x08, 0xFF, 0xBD, 0x6C), new ColorMatch(0x09, 0xFF, 0x54, 0x00), + new ColorMatch(0x0A, 0x59, 0x1D, 0x00), new ColorMatch(0x0B, 0x27, 0x18, 0x00), + new ColorMatch(0x0C, 0xFF, 0xFF, 0x4C), new ColorMatch(0x0D, 0xFF, 0xFF, 0x00), + new ColorMatch(0x0E, 0x59, 0x59, 0x00), new ColorMatch(0x0F, 0x19, 0x19, 0x00), + + new ColorMatch(0x10, 0x88, 0xFF, 0x4C), new ColorMatch(0x11, 0x54, 0xFF, 0x00), + new ColorMatch(0x12, 0x1D, 0x59, 0x00), new ColorMatch(0x13, 0x14, 0x28, 0x00), + new ColorMatch(0x14, 0x4C, 0xFF, 0x4C), new ColorMatch(0x15, 0x00, 0xFF, 0x00), + new ColorMatch(0x16, 0x00, 0x59, 0x00), new ColorMatch(0x17, 0x00, 0x19, 0x00), + new ColorMatch(0x18, 0x4C, 0xFF, 0x5E), new ColorMatch(0x19, 0x00, 0xFF, 0x19), + new ColorMatch(0x1A, 0x00, 0x59, 0x0D), new ColorMatch(0x1B, 0x00, 0x19, 0x02), + new ColorMatch(0x1C, 0x4C, 0xFF, 0x88), new ColorMatch(0x1D, 0x00, 0xFF, 0x55), + new ColorMatch(0x1E, 0x00, 0x59, 0x1D), new ColorMatch(0x1F, 0x00, 0x19, 0x12), + + new ColorMatch(0x20, 0x4D, 0x06, 0xC7), new ColorMatch(0x21, 0x55, 0x05, 0xFF), + new ColorMatch(0x22, 0x00, 0x1D, 0x71), new ColorMatch(0x23, 0x00, 0x00, 0x19), + new ColorMatch(0x24, 0x4C, 0xF8, 0xFF), new ColorMatch(0x25, 0x00, 0xA9, 0xFF), + new ColorMatch(0x26, 0x00, 0x41, 0x52), new ColorMatch(0x27, 0x00, 0x10, 0x19), + new ColorMatch(0x28, 0x4C, 0xE8, 0xFF), new ColorMatch(0x29, 0x00, 0x65, 0xFF), + new ColorMatch(0x2A, 0x00, 0x27, 0x52), new ColorMatch(0x2B, 0x00, 0x0C, 0x19), + new ColorMatch(0x2C, 0x4C, 0xD8, 0xFF), new ColorMatch(0x2D, 0x00, 0x00, 0xFF), + new ColorMatch(0x2E, 0x00, 0x11, 0x52), new ColorMatch(0x2F, 0x00, 0x04, 0x19), + + new ColorMatch(0x30, 0x87, 0xC7, 0xFF), new ColorMatch(0x31, 0x54, 0x00, 0xFF), + new ColorMatch(0x32, 0x19, 0x00, 0x52), new ColorMatch(0x33, 0x0F, 0x00, 0x19), + new ColorMatch(0x34, 0x4C, 0xA8, 0xFF), new ColorMatch(0x35, 0x00, 0x00, 0xFF), + new ColorMatch(0x36, 0x00, 0x00, 0x59), new ColorMatch(0x37, 0x00, 0x00, 0x19), + new ColorMatch(0x38, 0x4C, 0x88, 0xFF), new ColorMatch(0x39, 0x00, 0xA9, 0xFF), + new ColorMatch(0x3A, 0x00, 0x36, 0x4D), new ColorMatch(0x3B, 0x00, 0x0D, 0x19), + new ColorMatch(0x3C, 0x4C, 0x69, 0xFF), new ColorMatch(0x3D, 0x00, 0x54, 0xFF), + new ColorMatch(0x3E, 0x00, 0x1D, 0x59), new ColorMatch(0x3F, 0x00, 0x10, 0x19), + + new ColorMatch(0x40, 0x4C, 0x95, 0x00), new ColorMatch(0x41, 0x00, 0x2C, 0xB9), + new ColorMatch(0x42, 0x00, 0x08, 0x19), new ColorMatch(0x43, 0x00, 0x08, 0x19), + new ColorMatch(0x44, 0x4C, 0x69, 0xFF), new ColorMatch(0x45, 0x00, 0x00, 0xFF), + new ColorMatch(0x46, 0x00, 0x00, 0x59), new ColorMatch(0x47, 0x00, 0x00, 0x19), + new ColorMatch(0x48, 0x87, 0x67, 0xFF), new ColorMatch(0x49, 0x7A, 0x00, 0xFF), + new ColorMatch(0x4A, 0x19, 0x00, 0x52), new ColorMatch(0x4B, 0x0F, 0x00, 0x30), + new ColorMatch(0x4C, 0xFF, 0x4C, 0xFF), new ColorMatch(0x4D, 0xFF, 0x00, 0xFF), + new ColorMatch(0x4E, 0x59, 0x00, 0x59), new ColorMatch(0x4F, 0x19, 0x00, 0x19), + + new ColorMatch(0x50, 0xFF, 0x4C, 0xD8), new ColorMatch(0x51, 0xFF, 0x00, 0x54), + new ColorMatch(0x52, 0x59, 0x00, 0x1D), new ColorMatch(0x53, 0x22, 0x00, 0x13), + new ColorMatch(0x54, 0xFF, 0x4C, 0xAD), new ColorMatch(0x55, 0xFF, 0x00, 0x73), + new ColorMatch(0x56, 0x59, 0x00, 0x26), new ColorMatch(0x57, 0x19, 0x00, 0x0D), + new ColorMatch(0x58, 0xFF, 0x15, 0x00), new ColorMatch(0x59, 0x99, 0x35, 0x00), + new ColorMatch(0x5A, 0x79, 0x51, 0x00), new ColorMatch(0x5B, 0x43, 0x60, 0x00), + new ColorMatch(0x5C, 0x03, 0x38, 0x00), new ColorMatch(0x5D, 0x14, 0x4F, 0x10), + new ColorMatch(0x5E, 0x0D, 0x5C, 0x05), new ColorMatch(0x5F, 0x15, 0x62, 0x00), + + new ColorMatch(0x60, 0xFF, 0x90, 0x00), new ColorMatch(0x61, 0x88, 0xCC, 0x00), + new ColorMatch(0x62, 0x91, 0xCC, 0x00), new ColorMatch(0x63, 0x43, 0x74, 0x00), + new ColorMatch(0x64, 0x03, 0x39, 0x00), new ColorMatch(0x65, 0x00, 0x57, 0x45), + new ColorMatch(0x66, 0x00, 0x54, 0x7F), new ColorMatch(0x67, 0x00, 0x00, 0xFF), + new ColorMatch(0x68, 0x00, 0x45, 0x4F), new ColorMatch(0x69, 0x25, 0x00, 0xDC), + new ColorMatch(0x6A, 0x7F, 0x7F, 0x7F), new ColorMatch(0x6B, 0x20, 0x20, 0x20), + new ColorMatch(0x6C, 0xFF, 0x00, 0x00), new ColorMatch(0x6D, 0xBE, 0x2D, 0x2D), + new ColorMatch(0x6E, 0xB0, 0x18, 0x18), new ColorMatch(0x6F, 0x64, 0xF1, 0xD5), + + new ColorMatch(0x70, 0x10, 0x88, 0x00), new ColorMatch(0x71, 0x14, 0x4B, 0x00), + new ColorMatch(0x72, 0x07, 0x42, 0x00), new ColorMatch(0x73, 0x00, 0xA1, 0x00), + new ColorMatch(0x74, 0x39, 0x00, 0x00), new ColorMatch(0x75, 0x7A, 0x51, 0x00), + new ColorMatch(0x76, 0x73, 0x17, 0x00), new ColorMatch(0x77, 0x5B, 0xFF, 0x00), + new ColorMatch(0x78, 0x3B, 0xDD, 0x08), new ColorMatch(0x79, 0x59, 0xFF, 0x00), + new ColorMatch(0x7A, 0x38, 0xCE, 0x00), new ColorMatch(0x7B, 0x40, 0x40, 0x40), + new ColorMatch(0x7C, 0x75, 0x75, 0x75), new ColorMatch(0x7D, 0xE1, 0x20, 0x00), + new ColorMatch(0x7E, 0xB0, 0xB4, 0x00), new ColorMatch(0x7F, 0x4B, 0x15, 0x02)); + + private record ColorMatch(int index, int red, int green, int blue, Color color) { + public ColorMatch(final int index, final int red, final int green, final int blue) { + this(index, red, green, blue, Color.fromRGB255(red, green, blue)); + } + + public boolean isGrayTone() { + return red == green && green == blue; + } + + private double colorDistance(final double r1, final double g1, final double b1) { + final double dr = r1 - (this.red / 255.0); + final double dg = g1 - (this.green / 255.0); + final double db = b1 - (this.blue / 255.0); + + return Math.sqrt(dr * dr + dg * dg + db * db); // Euclidean distance + } + } + + private final int index; + private int state; + + public static final int OFF = 0; + public static final int WHITE_DIM = 0x1; + public static final int GREY = 0x2; + public static final int WHITE = 0x3; + public static final int RED = 0x5; + public static final int RED_DIM = 0x7; + public static final int YELLOW = 0x15; + public static final int YELLOW_DIM = 0x18; + public static final int ORANGE = 0x9; + public static final int ORANGE_DIM = 0xC; + public static final int GREEN = 0x15; + public static final int GREEN_DIM = 0x18; + public static final int BLUE = 0x2D; + public static final int BLUE_DIM = 0x2F; + + public static final int STATE_NORMAL = 0; + public static final int STATE_BLINK = 1; + public static final int STATE_PULSE = 2; + + public EraeColor(final int index) { + this.index = index; + this.state = state; + } + + public int getIndex() { + return index; + } + + public void setState(final int state) { + this.state = state; + } + + public int getState() { + return state; + } + + public static EraeColor toColor(final double r, final double g, final double b) { + final int colorIndex = rgbToIndex(r, g, b); + return new EraeColor(colorIndex); + } + + public static int rgbToIndex(final double red, final double green, final double blue) { + int closestIndex = -1; + double minDistance = Double.MAX_VALUE; + + if (red == green && green == blue) { + for (int i = 0; i < 128; i++) { + final ColorMatch c = COLOR_SEQ.get(i); + if (c.isGrayTone()) { + final double distance = c.colorDistance(red, green, blue); + if (distance < minDistance) { + minDistance = distance; + closestIndex = i; + } + } + } + } else { + for (int i = 0; i < 0x32; i++) { + final ColorMatch c = COLOR_SEQ.get(i); + final double distance = c.colorDistance(red, green, blue); + + if (distance < minDistance) { + minDistance = distance; + closestIndex = i; + } + } + } + + final ColorMatch colorMatch = COLOR_SEQ.get(closestIndex); + // Erae2ControllerExtension.println( + // "MATCH %02X = %02X %02X %02X %02X %02X %02X", closestIndex, colorMatch.red, colorMatch.green, + // colorMatch.blue, (int) Math.round(red * 255), (int) Math.round(green * 255), (int) Math.round + // (blue * 255)); + return colorMatch.index(); + } +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/EraeMidiProcessor.java b/src/main/java/com/bitwig/extensions/controllers/embodme/EraeMidiProcessor.java new file mode 100644 index 00000000..c4e7a48b --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/EraeMidiProcessor.java @@ -0,0 +1,116 @@ +package com.bitwig.extensions.controllers.embodme; + +import com.bitwig.extension.controller.api.ControllerHost; +import com.bitwig.extension.controller.api.MidiIn; +import com.bitwig.extension.controller.api.MidiOut; +import com.bitwig.extension.controller.api.NoteInput; + +public class EraeMidiProcessor { + private static final String IDENT_REQUEST = "f0 7e 7f 06 01 f7"; + private static final String IDENT_REPLY = "f07e0106020021500001000256010102f7"; + private static final String ERAE_SYSEX_HEADER = "F0 00 21 50 00 01 00 02 01 01 "; + private static final String REQUEST_STATE = ERAE_SYSEX_HEADER + "02 03 F7"; + private static final String IN_ERAE_SYSEX_HEADER = "f0002150000300012"; + + private static final byte[] BUTTON_UPDATE = { + (byte) 0xF0, 0x00, 0x21, 0x50, 0x00, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, // + 0x1B,// 12: index row*12 + columnn + 0x01, // 13: color style 0x0 const 0x1 blink 0x2 pulse + 0x05, // 14: color + (byte) 0xF7 + }; + + private static final byte[] ACTION_BUTTON_UPDATE = { + (byte) 0xF0, 0x00, 0x21, 0x50, 0x00, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x01, // + 0x1B,// 12: index row*12 + columnn + 0x01, // 13: color style 0x0 const 0x1 blink 0x2 pulse + 0x05, // 14: color + (byte) 0xF7 + }; + + // F0 00 21 50 00 01 00 02 01 01 02 0F [target_id] [value] F7 + private static final byte[] SLIDER_UPDATE = { + (byte) 0xF0, 0x00, 0x21, 0x50, 0x00, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x0F, // + 0x01, // 12: target Id + 0x05, // 13: value + (byte) 0xF7 + }; + + private final MidiIn midiInDaw; + private final MidiOut midiOutDaw; + private final Erae2ControllerExtension controller; + + public EraeMidiProcessor(final ControllerHost host, final Erae2ControllerExtension controller) { + this.controller = controller; + midiInDaw = host.getMidiInPort(0); + midiOutDaw = host.getMidiOutPort(0); + midiInDaw.createNoteInput("Erae MIDI Port", "??????"); + midiInDaw.setSysexCallback(this::handleSysEx); + + final MidiIn noteMidiIn = host.getMidiInPort(1); + final NoteInput noteInputMpe = noteMidiIn.createNoteInput("Erae MPE Port", "??????"); + noteInputMpe.setUseExpressiveMidi(true, 0, 48); + } + + public void init() { + midiOutDaw.sendSysex(IDENT_REQUEST); + } + + + private void handleSysEx(final String fullData) { + if (fullData.startsWith(IN_ERAE_SYSEX_HEADER)) { + final String data = fullData.substring(IN_ERAE_SYSEX_HEADER.length() + 1, fullData.length() - 2); + + if ("2c".equals(data)) { + midiOutDaw.sendSysex(REQUEST_STATE); + } else if (data.startsWith("26")) { + final int size = Integer.parseInt(data.substring(2, 4), 16); + final int mode = Integer.parseInt(data.substring(4, 6), 16); + controller.handleMode(size, mode); + } else if (data.startsWith("01")) { + final int buttonIndex = Integer.parseInt(data.substring(2, 4), 16); + final int value = Integer.parseInt(data.substring(4, 6), 16); + controller.handleIndexButton(buttonIndex, value > 0); + } else if (data.startsWith("02")) { + final int buttonIndex = Integer.parseInt(data.substring(2, 4), 16); + final int value = Integer.parseInt(data.substring(4, 6), 16); + final int row = buttonIndex / 12; + final int col = buttonIndex % 12; + controller.handleGridButton(row, col, value > 0); + } else if (data.startsWith("0f")) { + final int sliderIndex = Integer.parseInt(data.substring(2, 4), 16); + final int value = Integer.parseInt(data.substring(4, 6), 16); + controller.handleSlider(sliderIndex, value); + } else { + Erae2ControllerExtension.println(" DATA = %s", data); + } + } else if (fullData.equals(IDENT_REPLY)) { + Erae2ControllerExtension.println(" IDENT REPLY"); + midiOutDaw.sendSysex(REQUEST_STATE); + } else { + Erae2ControllerExtension.println(" SysEx = %s", fullData); + } + } + + public void sendGridButtonUpdate(final int row, final int column, final int style, final int color) { + BUTTON_UPDATE[12] = (byte) ((row * 12 + column) & 0x7F); + BUTTON_UPDATE[13] = (byte) (style & 0x7F); + BUTTON_UPDATE[14] = (byte) (color & 0x7F); + midiOutDaw.sendSysex(BUTTON_UPDATE); + } + + public void sendActionButtonUpdate(final int index, final int style, final int color) { + ACTION_BUTTON_UPDATE[12] = (byte) (index & 0x7F); + ACTION_BUTTON_UPDATE[13] = (byte) (style & 0x7F); + ACTION_BUTTON_UPDATE[14] = (byte) (color & 0x7F); + midiOutDaw.sendSysex(ACTION_BUTTON_UPDATE); + } + + public void sendSliderUpdate(final int targetId, final int value) { + SLIDER_UPDATE[12] = (byte) (targetId & 0x7F); + SLIDER_UPDATE[13] = (byte) (value & 0x7F); + midiOutDaw.sendSysex(SLIDER_UPDATE); + } + + +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/SceneState.java b/src/main/java/com/bitwig/extensions/controllers/embodme/SceneState.java new file mode 100644 index 00000000..f6fb5d08 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/SceneState.java @@ -0,0 +1,69 @@ +package com.bitwig.extensions.controllers.embodme; + +class SceneState { + private final int index; + private int count; + private int state = 0; + private int color = EraeColor.GREEN; + private int displayColor = 0; + private boolean exists; + private boolean queued; + + public SceneState(final int index) { + this.index = index; + } + + public void setCount(final int count) { + this.count = count; + } + + public void setColor(final int color) { + if (color == 0x7b) { + this.color = EraeColor.GREEN; + } else { + this.color = color; + } + } + + public int getIndex() { + return index; + } + + public int getCount() { + return count; + } + + public int getState() { + return state; + } + + public int getDisplayColor() { + return displayColor; + } + + public boolean calcState() { + final int oldState = this.state; + final int oldColor = this.displayColor; + + if (exists) { + if (queued) { + displayColor = color; + } else if (count == 0) { + displayColor = 0; + } else { + displayColor = color + 2; + } + state = queued ? 1 : 0; + } + + return oldState != state || oldColor != displayColor; + } + + public void setExists(final boolean exists) { + this.exists = exists; + } + + public void setQueued(final boolean queued) { + this.queued = queued; + } +} diff --git a/src/main/java/com/bitwig/extensions/controllers/embodme/TrackState.java b/src/main/java/com/bitwig/extensions/controllers/embodme/TrackState.java new file mode 100644 index 00000000..3a4e77b9 --- /dev/null +++ b/src/main/java/com/bitwig/extensions/controllers/embodme/TrackState.java @@ -0,0 +1,57 @@ +package com.bitwig.extensions.controllers.embodme; + +import com.bitwig.extension.controller.api.Track; + +class TrackState { + private final Track track; + private final int index; + private boolean armed; + private boolean muted; + private boolean solo; + private int color; + + public TrackState(final Track track, final int trackIndex) { + this.track = track; + this.index = trackIndex; + } + + public Track getTrack() { + return track; + } + + public int getIndex() { + return index; + } + + public void setArmed(final boolean armed) { + this.armed = armed; + } + + public boolean isArmed() { + return armed; + } + + public boolean isMuted() { + return muted; + } + + public void setMuted(final boolean muted) { + this.muted = muted; + } + + public boolean isSolo() { + return solo; + } + + public void setSolo(final boolean solo) { + this.solo = solo; + } + + public int getColor() { + return color; + } + + public void setColor(final int color) { + this.color = color; + } +} diff --git a/src/main/resources/Documentation/Controllers/Embodme/Embodme Erae 2.pdf b/src/main/resources/Documentation/Controllers/Embodme/Embodme Erae 2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..412acb5961e6c31e80df3137ad8e5271a0eb2e7d GIT binary patch literal 96281 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 Date: Wed, 12 Aug 2026 20:59:30 +0200 Subject: [PATCH 4/4] Fix Overview --- .../framework/view/OverviewGrid.java | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/bitwig/extensions/framework/view/OverviewGrid.java b/src/main/java/com/bitwig/extensions/framework/view/OverviewGrid.java index 87cb488e..443f74c1 100644 --- a/src/main/java/com/bitwig/extensions/framework/view/OverviewGrid.java +++ b/src/main/java/com/bitwig/extensions/framework/view/OverviewGrid.java @@ -1,5 +1,8 @@ package com.bitwig.extensions.framework.view; +import java.util.ArrayList; +import java.util.List; + import com.bitwig.extension.controller.api.ClipLauncherSlot; import com.bitwig.extension.controller.api.Scene; import com.bitwig.extension.controller.api.Track; @@ -21,6 +24,12 @@ public class OverviewGrid { private final int size; private final TrackBank maxTrackBank; + private final List queueChangeListeners = new ArrayList<>(); + + @FunctionalInterface + public interface QueueChangeListener { + void notifySceneHasQueued(int index, boolean queued); + } public OverviewGrid(final TrackBank maxTrackBank) { this.size = maxTrackBank.getSizeOfBank(); @@ -31,6 +40,19 @@ public OverviewGrid(final TrackBank maxTrackBank) { prepare(maxTrackBank); } + public void initMaxBank() { + for (int i = 0; i < size; i++) { + final int trackIndex = i; + final Track track = maxTrackBank.getItemAt(trackIndex); + for (int j = 0; j < track.clipLauncherSlotBank().getSizeOfBank(); j++) { + final int sceneIndex = j; + final ClipLauncherSlot slot = track.clipLauncherSlotBank().getItemAt(sceneIndex); + slot.isPlaybackQueued().addValueObserver(isQueued -> markSceneQueued(sceneIndex, isQueued)); + slot.isPlaying().addValueObserver(isQueued -> markScenePlaying(sceneIndex, isQueued)); + } + } + } + public void setUpFocusScene(final TrackBank mainBank) { prepare(mainBank); mainBank.sceneBank().itemCount().addValueObserver(this::setNumberOfScenes); @@ -47,19 +69,11 @@ public void setUpFocusScene(final TrackBank mainBank) { maxTrackBank.sceneBank().scrollPosition().set(getSceneOffset()); } }); - for (int i = 0; i < size; i++) { - final int trackIndex = i; - final Track track = maxTrackBank.getItemAt(trackIndex); - - final Scene scene = maxTrackBank.sceneBank().getScene(i); - scene.clipCount().addValueObserver(count -> this.clipCount[trackIndex] = count); - for (int j = 0; j < size; j++) { - final int sceneIndex = j; - final ClipLauncherSlot slot = track.clipLauncherSlotBank().getItemAt(sceneIndex); - slot.isPlaybackQueued().addValueObserver(isQueued -> markSceneQueued(sceneIndex, isQueued)); - slot.isPlaying().addValueObserver(isQueued -> markScenePlaying(sceneIndex, isQueued)); - } - } + initMaxBank(); + } + + public void addQueuedSceneListener(final QueueChangeListener listener) { + queueChangeListeners.add(listener); } public int getNumberOfScenes() { @@ -105,11 +119,17 @@ public int getSceneOffset() { } private void markSceneQueued(final int sceneIndex, final boolean isQueued) { + final int previous = sceneQueuedClips[sceneIndex]; if (isQueued) { sceneQueuedClips[sceneIndex]++; } else if (sceneQueuedClips[sceneIndex] > 0) { sceneQueuedClips[sceneIndex]--; } + if (sceneQueuedClips[sceneIndex] > 0 && previous == 0) { + queueChangeListeners.forEach(l -> l.notifySceneHasQueued(sceneIndex, true)); + } else if (sceneQueuedClips[sceneIndex] <= 0 && previous > 0) { + queueChangeListeners.forEach(l -> l.notifySceneHasQueued(sceneIndex, false)); + } } private void markScenePlaying(final int sceneIndex, final boolean isPlaying) {