Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.bitwig.extension.api.Color;
Expand All @@ -14,9 +13,6 @@
import com.bitwig.extension.controller.api.ControllerHost;
import com.bitwig.extension.controller.api.CursorRemoteControlsPage;
import com.bitwig.extension.controller.api.CursorTrack;
import com.bitwig.extension.controller.api.Device;
import com.bitwig.extension.controller.api.DeviceBank;
import com.bitwig.extension.controller.api.DeviceMatcher;
import com.bitwig.extension.controller.api.DocumentState;
import com.bitwig.extension.controller.api.HardwareButton;
import com.bitwig.extension.controller.api.HardwareElement;
Expand Down Expand Up @@ -260,15 +256,13 @@ protected void initTrackBank() {

if (hasDeviceControl()) {
mixerTrackBank.scrollPosition().addValueObserver(this::handleTrackScrollChanged);
} else {
for (final NksDevice deviceType : NksDevice.values()) {
final SpecificPluginDevice specDevice = deviceType.createSpecDevice(cursorDevice);
final Parameter instId = specDevice.createParameter(deviceType.getParamOffset());
instId.name().addValueObserver(id -> midiProcessor.registerNksParam(deviceType, id));
}
}
// else {
// for (final NksDevice deviceType : NksDevice.values()) {
// final SpecificPluginDevice specDevice = deviceType.createSpecDevice(cursorDevice);
// final Parameter instId = specDevice.createParameter(deviceType.getParamOffset());
// instId.name().addValueObserver(midiProcessor::updateKompleteKontrolInstance);
// }
// }
initNksDiscovery(cursorTrack);

mainLayer.bindPressed(controlElements.getMuteSelectedButton(), cursorTrack.mute().toggleAction());
mainLayer.bindPressed(controlElements.getSoloSelectedButton(), cursorTrack.solo().toggleAction());
Expand All @@ -283,22 +277,6 @@ protected void initTrackBank() {
}
}

private void initNksDiscovery(final CursorTrack cursorTrack) {
final DeviceBank nksDiscoverBank = cursorTrack.createDeviceBank(1);
final DeviceMatcher matcher = getHost().createOrDeviceMatcher(Arrays.stream(NksDevice.values()) //
.map(type -> type.createMatcher(getHost())) //
.toArray(DeviceMatcher[]::new));

nksDiscoverBank.setDeviceMatcher(matcher);
final Device nksDevice = nksDiscoverBank.getDevice(0);
for (final NksDevice deviceType : NksDevice.values()) {
final SpecificPluginDevice specDevice = deviceType.createSpecDevice(nksDevice);
final Parameter instId = specDevice.createParameter(deviceType.getParamOffset());
instId.name().addValueObserver(name -> midiProcessor.registerNksParam(deviceType, name));
}
nksDevice.name().addValueObserver(name -> midiProcessor.registerNksDevice(name));
}

private void handleTrackScrollChanged(final int pos) {
midiProcessor.refreshSelectedColor();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.bitwig.extensions.controllers.nativeinstruments.komplete;

import java.util.Arrays;

import com.bitwig.extension.controller.api.Application;
import com.bitwig.extension.controller.api.ControllerHost;
import com.bitwig.extension.controller.api.CursorTrack;
import com.bitwig.extension.controller.api.DeviceMatcher;
import com.bitwig.extension.controller.api.PinnableCursorDevice;
import com.bitwig.extension.controller.api.Project;
import com.bitwig.extension.controller.api.TrackBank;
Expand All @@ -14,6 +17,7 @@ public class ViewControl {
private final NavigationState navigationState = new NavigationState();
private final CursorTrack cursorTrack;
private final PinnableCursorDevice cursorDevice;
private final DeviceMatcher nksDeviceMatcher;
protected TrackBank mixerTrackBank;
protected Transport transport;
protected Project project;
Expand All @@ -35,12 +39,21 @@ public ViewControl(final ControllerHost host) {
mixerTrackBank.canScrollChannelsUp().markInterested();
mixerTrackBank.followCursorTrack(cursorTrack);
mixerTrackBank.setChannelScrollStepSize(8);

nksDeviceMatcher = host.createOrDeviceMatcher(Arrays.stream(NksDevice.values()) //
.map(type -> type.createMatcher(host)) //
.toArray(DeviceMatcher[]::new));

}

public Project getProject() {
return project;
}

public DeviceMatcher getNksDeviceMatcher() {
return nksDeviceMatcher;
}

public NavigationState getNavigationState() {
return navigationState;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public DeviceControl(final ControllerHost host, final MidiProcessor midiProcesso
this.controlElements = controlElements;
final PinnableCursorDevice cursorDevice = cursorTrack.createCursorDevice();
cursorDevice.presetName().addValueObserver(this::handlePresetName);

this.mainBank = new BankControl(cursorDevice, this.midiProcessor, this, controlElements.getShiftHeld());
this.mainBank.getCurrentFocus().addValueObserver(this::handleFocus);
final BrowserHandler browserHandler = new BrowserHandler(host, cursorDevice, controlElements.getShiftHeld());
Expand All @@ -63,8 +64,7 @@ public DeviceControl(final ControllerHost host, final MidiProcessor midiProcesso
deviceRemotesControl = new RemotesControl(deviceRemoteLayer, deviceRemotePages, controlElements, midiProcessor);
directParameterControl =
new DirectParameterControl(
directParamLayer, cursorDevice, controlElements, midiProcessor,
deviceRemotePages.pageCount());
directParamLayer, viewControl, controlElements, midiProcessor, deviceRemotePages.pageCount());
directParameterControl.getDirectActive().addValueObserver(this::handleDirectActive);

final Track rootTrack = viewControl.getProject().getRootTrackGroup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import java.util.HashMap;
import java.util.List;

import com.bitwig.extension.controller.api.CursorDevice;
import com.bitwig.extension.controller.api.Device;
import com.bitwig.extension.controller.api.DirectParameterValueDisplayObserver;
import com.bitwig.extension.controller.api.IntegerValue;
import com.bitwig.extension.controller.api.Parameter;
import com.bitwig.extension.controller.api.RelativeHardwareKnob;
import com.bitwig.extension.controller.api.SpecificPluginDevice;
import com.bitwig.extensions.controllers.nativeinstruments.komplete.NksDevice;
import com.bitwig.extensions.controllers.nativeinstruments.komplete.ViewControl;
import com.bitwig.extensions.controllers.nativeinstruments.komplete.binding.KnobDirectBinding;
import com.bitwig.extensions.controllers.nativeinstruments.komplete.control.ControlElements;
import com.bitwig.extensions.controllers.nativeinstruments.komplete.midi.MidiProcessor;
Expand All @@ -35,11 +38,17 @@ public class DirectParameterControl extends AbstractParameterControl {
private String deviceName;
private boolean fineTune;

public DirectParameterControl(final Layer layer, final CursorDevice device, final ControlElements controlElements,
final MidiProcessor midiProcessor, final IntegerValue remotePageCount) {
public DirectParameterControl(final Layer layer, final ViewControl viewControl,
final ControlElements controlElements, final MidiProcessor midiProcessor, final IntegerValue remotePageCount) {
super(layer);
this.device = viewControl.getCursorDevice();
this.midiProcessor = midiProcessor;
this.device = device;
for (final NksDevice deviceType : NksDevice.values()) {
final SpecificPluginDevice specDevice = deviceType.createSpecDevice(device);
final Parameter instId = specDevice.createParameter(deviceType.getParamOffset());
instId.name().addValueObserver(name -> midiProcessor.registerNksParam(deviceType, name));
}

for (int i = 0; i < MAX_PARAMS; i++) {
allSlots.add(new DirectSlot(i));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.bitwig.extensions.controllers.nativeinstruments.komplete.device.DeviceSelectionTab;

public class MidiProcessor {
private long initStartTime;
final NhiaSyexLevelsCommand trackLevelMeterCommand = new NhiaSyexLevelsCommand(0x49);
private final static String INCOMING_HEADER = "f0002109000044430100";
private final static String INCOMING_INDEX = INCOMING_HEADER + "7000";
Expand Down Expand Up @@ -81,6 +82,19 @@ private void handleSysex(final String sysExData) {
public void intoDawMode(final int protocol) {
this.expectedProtocol = protocol;
midiOut.sendMidi(0xBF, 0x1, protocol);
host.scheduleTask(this::initProcess, 1000);
initStartTime = System.currentTimeMillis();
}

private void initProcess() {
final long diff = System.currentTimeMillis() - initStartTime;
KompleteKontrolExtension.println(" Running Init Process %d kk=%s", diff, lastReportedKKInstance);
if (diff < 20000) {
host.scheduleTask(this::initProcess, 1000);
}
if (lastReportedKKInstance != null) {
sendTextCommand(TextCommand.SELECTED_TRACK, lastReportedKKInstance);
}
}

public void delay(final Runnable action, final int delay) {
Expand Down Expand Up @@ -143,26 +157,12 @@ public HardwareButton createButton(final String name, final int ccNr, final int
return hwButton;
}

private String currentNksDeviceName = "";

public void registerNksDevice(final String name) {
currentNksDeviceName = name;
}

public void registerNksParam(final NksDevice deviceTyp, final String paramId) {
if (!paramId.isBlank()) {
updateKompleteKontrolInstance(paramId);
}
}

public void updateKompleteKontrolInstance(final String instanceParamName) {
if (instanceParamName.isBlank()) {
return;
}
if (lastReportedKKInstance == null || !lastReportedKKInstance.equals(instanceParamName)) {
sendTextCommand(TextCommand.SELECTED_TRACK, instanceParamName);
host.scheduleTask(() -> sendTextCommand(TextCommand.SELECTED_TRACK, instanceParamName), 100);
lastReportedKKInstance = instanceParamName;
// KompleteKontrolExtension.println(" REG NKS %s : %s ", lastReportedKKInstance, paramId);
if (lastReportedKKInstance == null || !lastReportedKKInstance.equals(paramId)) {
sendTextCommand(TextCommand.SELECTED_TRACK, paramId);
host.scheduleTask(() -> sendTextCommand(TextCommand.SELECTED_TRACK, paramId), 100);
lastReportedKKInstance = paramId;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class LaunchkeyMk4Extension extends ControllerExtension {
private HardwareSurface surface;
private Layer mainLayer;
private Layer shiftLayer;
private final boolean isMini;
private final LaunchkeyMk4Type type;
private MidiProcessor midiProcessor;
private SessionLayer sessionLayer;
private Layer currentMainModeLayer;
Expand All @@ -42,9 +42,9 @@ public static void println(final String format, final Object... args) {
}

public LaunchkeyMk4Extension(final AbstractLaunchkeyMk4ExtensionDefinition definition, final ControllerHost host,
final boolean miniVersion) {
final LaunchkeyMk4Type type) {
super(definition, host);
this.isMini = miniVersion;
this.type = type;
}

@Override
Expand All @@ -53,7 +53,7 @@ public void init() {
final ControllerHost host = diContext.getService(ControllerHost.class);
debugHost = host;
surface = diContext.getService(HardwareSurface.class);
midiProcessor = new MidiProcessor(host, isMini);
midiProcessor = new MidiProcessor(host, type);
diContext.registerService(MidiProcessor.class, midiProcessor);

mainLayer = diContext.createLayer("MAIN");
Expand Down Expand Up @@ -160,7 +160,7 @@ public void initControl(final Context diContext) {

mainLayer.bind(hwElements.getMasterSlider(), masterTrack.volume());

preapareTransport(transport);
prepareTransport(transport);

hwElements.getButton(CcAssignments.PLAY).bindPressed(mainLayer, () -> handleRestartPlay(transport));
hwElements.getButton(CcAssignments.PLAY).bindLightOnOff(mainLayer, transport.isPlaying());
Expand All @@ -186,7 +186,7 @@ public void initControl(final Context diContext) {
undoButton.bindLightOnOff(shiftLayer, application.canRedo());
}

private static void preapareTransport(final Transport transport) {
private static void prepareTransport(final Transport transport) {
transport.isPlaying().markInterested();
transport.isMetronomeEnabled().markInterested();
transport.isClipLauncherOverdubEnabled().markInterested();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.bitwig.extensions.controllers.novation.launchkey_mk4;

public enum LaunchkeyMk4Type {
STANDARD((byte) 0x14),
MINI((byte) 0x13);

private final byte sysExCode;

LaunchkeyMk4Type(final byte sysExCode) {
this.sysExCode = sysExCode;
}

public byte getSysExCode() {
return sysExCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.bitwig.extensions.framework.time.TimedEvent;

public class MidiProcessor {
private static final String DEVICE_INQUIRY = "F0 7E 7F 06 01 F7";
private static final String NOVATION_HEADER = "F0 00 20 29 02 %02X ";
private static final byte[] TEXT_CONFIG_COMMAND =
{(byte) 0xF0, 0x00, 0x20, 0x29, 0x02, 0x14, 0x04, 0x00, 0x00, (byte) 0xF7};
Expand All @@ -30,26 +29,20 @@ public class MidiProcessor {
private final MidiOut midiOut;
private final NoteInput noteInput;
private int blinkCounter = 0;
private final boolean miniVersion;
private final LaunchkeyMk4Type launchkeyType;
private final Queue<TimedEvent> timedEvents = new LinkedList<>();
private final MidiOut midiOut2;
private final List<ModeListener> modeListeners = new ArrayList<>();
private final List<NoteHandler> noteHandlers = new ArrayList<>();
private final String header;
private final int modelIdCode;
private final NoteInput padNoteInput;

public MidiProcessor(final ControllerHost host, final boolean mini) {
public MidiProcessor(final ControllerHost host, final LaunchkeyMk4Type type) {
this.host = host;
this.miniVersion = mini;
this.modelIdCode = mini ? 0x13 : 0x14;
this.header = NOVATION_HEADER.formatted(modelIdCode);
if (mini) {
TEXT_CONFIG_COMMAND[5] = 0x13;
}
this.launchkeyType = type;
this.header = NOVATION_HEADER.formatted(type.getSysExCode());
TEXT_CONFIG_COMMAND[5] = type.getSysExCode();
this.midiIn = host.getMidiInPort(0);
this.midiOut = host.getMidiOutPort(0);
this.midiOut2 = host.getMidiOutPort(1);

padNoteInput = midiIn.createNoteInput("DRUM", "89????", "99????", "A?????");

Expand All @@ -70,15 +63,14 @@ public String getSysexHeader() {
}

public boolean isMiniVersion() {
return miniVersion;
return launchkeyType == LaunchkeyMk4Type.MINI;
}

public void addModeListener(final ModeListener listener) {
this.modeListeners.add(listener);
}

private void handleMidiIn(final int statusByte, final int data1, final int data2) {
final int cmd = statusByte & 0xF0;
if (statusByte == 0xB6) {
if (data1 == 0x1E) {
fireMode(ModeType.ENCODER, data2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ private void toggleMode() {
if (this.mode == Mode.ARM) {
this.currentLayer = selectLayer;
this.mode = Mode.SELECT;
displayControl.show2Line("Fader Mode", "Arm");
displayControl.show2Line("Fader Mode", "Select");
} else {
this.currentLayer = armLayer;
this.mode = Mode.ARM;
displayControl.show2Line("Fader Mode", "Select");
displayControl.show2Line("Fader Mode", "Arm");
}
this.currentLayer.setIsActive(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.bitwig.extension.controller.AutoDetectionMidiPortNamesList;
import com.bitwig.extension.controller.api.ControllerHost;
import com.bitwig.extensions.controllers.novation.launchkey_mk4.LaunchkeyMk4Extension;
import com.bitwig.extensions.controllers.novation.launchkey_mk4.LaunchkeyMk4Type;

public class LaunchkeyMiniMk4ExtensionDefinition extends AbstractLaunchkeyMk4ExtensionDefinition {
private static final UUID DRIVER_ID = UUID.fromString("ef68e909-d5f1-4557-8526-2ce6978fabcc");
Expand Down Expand Up @@ -76,7 +77,7 @@ public void listAutoDetectionMidiPortNames(final AutoDetectionMidiPortNamesList

@Override
public LaunchkeyMk4Extension createInstance(final ControllerHost host) {
return new LaunchkeyMk4Extension(this, host, true);
return new LaunchkeyMk4Extension(this, host, LaunchkeyMk4Type.MINI);
}

}
Loading
Loading